Will Newspeak be callable by external programs?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Will Newspeak be callable by external programs?

askoh
Administrator
Learning from Squeak's mistake, I am eager to know if Newspeak programs can be called by external programs. Can Newspeak programs be made into plugins or addons to non-Newspeak programs? Is it going to be able to control and be controlled by existing and future software? Is there any estimate of a release date?

All the best,
Aik-Siong Koh
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

Michael Haupt-3
Hi,

On Sun, Feb 8, 2009 at 7:43 AM, askoh <[hidden email]> wrote:
> Learning from Squeak's mistake,

what do you mean?

> I am eager to know if Newspeak programs can
> be called by external programs. ...

I don't quite know if I understand you correctly, but there is a
sophisticated FFI implementation (called "Alien FFI") that comes with
a robust callback mechanism. So, yes, it is possible to make calls
into the image from, e.g., C code. Does that answer your question?

> Is there any estimate of a release date?

I'm not the one to give a definitive answer here, but Gilad Bracha
wrote it would be "Real Soon Now :-)" (capitalised and smileyed as
quoted) on January 13th. See
http://gbracha.blogspot.com/2009/01/apologia.html

Best,

Michael

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

askoh
Administrator
For about a year now, I have been asking if Squeak can be called by external programs, if it can be controlled by a non-Squeak program, if it can be used to make plugins or addons in CAD programs. And I have not received an answer that says that it is possible now nor anyone working on that for the future. If Alien FFI can do it I would be most happy to try it immediately. Can the author of Alien FFI give an authoritative answer to its capability to do the above? Is there documentation to describe how? Thanks in advance.

All the best,
Aik-Siong Koh


Michael Haupt-3 wrote
Hi,

On Sun, Feb 8, 2009 at 7:43 AM, askoh <askoh@askoh.com> wrote:
> Learning from Squeak's mistake,

what do you mean?

> I am eager to know if Newspeak programs can
> be called by external programs. ...

I don't quite know if I understand you correctly, but there is a
sophisticated FFI implementation (called "Alien FFI") that comes with
a robust callback mechanism. So, yes, it is possible to make calls
into the image from, e.g., C code. Does that answer your question?

> Is there any estimate of a release date?

I'm not the one to give a definitive answer here, but Gilad Bracha
wrote it would be "Real Soon Now :-)" (capitalised and smileyed as
quoted) on January 13th. See
http://gbracha.blogspot.com/2009/01/apologia.html

Best,

Michael
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

Michael Haupt-3
Hi again,

one thing I forgot to mention is that Alien FFI has been made
available for Squeak. Maybe your woes come to an end.
http://wiki.squeak.org/squeak/6100

Best,

Michael

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

johnmci
In reply to this post by askoh
Ok, let me ramble.

Well in the far past for the macintosh we built a plugin for the  
browser.

The plugin used the netscape browser api to interface to the netscape  
and IE browser.
When the plugin was loaded it would set things up, and start running  
the bytecode interpreter.

The VM can be viewed as endless loop, however it is possible to exit  
the loop and return to the caller
and of course save the interpreter stack state.  Later the caller  
reenters the interpreter loop and continues
execution.

This logic still exists see

http://isqueak.org/browserPluginReturnIfNeeded

In the early part of the decade I change the logic a bit so that the  
interpreter was spin off as a separate pthread within
the browser to give us better performance and visual updating.


The Hydra VM still exploits this idea of returning from the  
interpreter loop where it does

        lockInterpreter(intr); /* lock interpreter mutex before entering loop  
*/
        while (1)
        {
                interpret(intr);
                // give a chance other threads to do something
                unlockInterpreter(intr);
                lockInterpreter(intr);
                pokeAtTimer(intr);
                handleEvents(intr);
        }


In this case the interpret() is the endless bytecode interpreter loop,  
which is exited, then the handleEvents
pulls inter-interpeter events off the queue and we re-enter the  
interpreter.  The other point is the program setups each
VM on a seperate pthread.


The iPhone VM actually runs the VM in a background thread

         // Run the squeak process in a worker thread
       
        [NSThread detachNewThreadSelector: @selector(runSqueak)
                                                         toTarget: self.squeakApplication
                                                   withObject: NULL];


For the current Unix and macintosh browser plugin we take a different  
approach where the plugin launches a separate
Squeak VM process and uses pipes and shared memory to move items of  
interest between the two process.  So UI gestures enter the browser  
plugin
and are sent by a pipe to the squeak process, the squeak process  
interpreters them, and does updates to it's internal Screen. For the  
unix port that's
a X11 screen hosted by the browser, for the carbon VM it's more  
complicated and has to us a shared memory location and pipe to ask the  
browser
plugin to draw the screen within the address space of the browser.    
Lastly the VM can make requests back to the browser, say to download a  
file, again
by sending a message via the pipe.

Astute macintosh folks might note for years now the Squeak carbon app  
will act as a Service, if you have a Squeak image that contains the  
macintosh services logic
it's possible for you to select smalltalk code in TextEdit, then say  
Services->Squeak DoIt and Squeak will get the services request, do it,  
and return the results.

Now for your problem.


(a) You want to run the VM, you can choose to run the VM either as  
part of a currently executing caller thread, or as a pthread, or as a  
separate process.
(b) You need to choose if you want to start the VM, execute some sort  
of startup script & data, return results, and quit.
(b) or pass a request to execute something, and return the result  
somehow.   There are many ways to do that, file based message passing,  
pipes, queues, shared memory, etc....

The Alien FFI work, or the older FFI logic will help you extract  
information from memory and/or call API routines hosted by the  
operating system or any other loadable DLL.
The Alien FFI work has logic to let you call back to a squeak method  
from a blocking API call that requires you to provide executable entry  
points, an example given
is the sort callback where the executable entry point you provide is a  
smalltalk method to compare floating point numbers.


What I'd suggest is having your plugin start the VM as a separate  
pthread with a thread safe queue, and location for the squeak external  
semaphore number. Your Squeak image would startup and wait on the  
semaphore.  Later when your CAD system invokes the plugin with lots of  
parameter data you build a queue object, put it on the queue, trigger  
the squeak semaphore and wait.... , once the waiting ends you have  
someway to pull the results that Squeak has made for you, likely  
populate the queue item with return data, and or of course the squeak  
vm could have manipulated the data to no end.

I'll note for the Objective-C bridge I'm working on for the iPhone has  
this chunk of code below (original donated by Avi)

What happens here is a message send occurs to a squeak proxy object,  
if the message selector is one we
are interested in we set a pthread conditional lock to :0, then unlock  
to 1, then signal the squeak semaphore.
the waiting squeak process then locks to condition 1, and the  
objective C code below then attempts an unlock to
condition 2 and will block as the squeak process runs using the  
NSInvocation instance which contains information
about the message send, all the parms and has the ability to set the  
return value.  Effectively we have the entire message
implementation in Smalltalk.  Once the Smalltalk logic completes it  
unlocks condition with condition 2 which lets the  ockWhenCondition: 2
thus letting the forwardInvocation: terminate.

In this case the SqueakProxy instance is being sent messages on the  
main thread, and the squeak VM is on another thread
the conditional lock control which thread gets   executed and the  
invocation instance variable is the shared object.

So what about NSDate?   The issue with passing data to complex third  
party is how long do you wait for the third party
to complete the request. What if your Smalltalk logic is flawed, and  
you get a walkback? Do you wait and time out or
do you return a bad value event by trapping the unhandled walkback?

- (void) forwardInvocation: (NSInvocation*) anInvocation
{
        NSDate *timeout;
        if (![sigs containsObject: NSStringFromSelector([anInvocation  
selector])]) {
                return;
        }
       
        if([lock lockWhenCondition: 0 beforeDate: (timeout = [[NSDate alloc]  
initWithTimeIntervalSinceNow: 3])])
        {
                [lock unlockWithCondition: 1];
                [timeout release];
                invocation = [anInvocation retain];
               
                interpreterProxy->signalSemaphoreWithIndex(sem);
                if([lock lockWhenCondition: 2 beforeDate: (timeout = [[NSDate alloc]  
initWithTimeIntervalSinceNow: 4])])
                {
                        [timeout release];
                        [invocation release];
                        [lock unlockWithCondition: 0];
                }
                else
                {
                        [timeout release];
                        [invocation release];
                        [lock unlockWithCondition: 0];
                }
        }
        else
        {
                [timeout release];
                //NSLog(@"failed lock 0");
        }
}


On 8-Feb-09, at 11:28 AM, askoh wrote:

>
> For about a year now, I have been asking if Squeak can be called by  
> external
> programs, if it can be controlled by a non-Squeak program, if it can  
> be used
> to make plugins or addons in CAD programs. And I have not received  
> an answer
> that says that it is possible now nor anyone working on that for the  
> future.
> If Alien FFI can do it I would be most happy to try it immediately.  
> Can the
> author of Alien FFI give an authoritative answer to its capability  
> to do the
> above? Is there documentation to describe how? Thanks in advance.
>
> All the best,
> Aik-Siong Koh

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

askoh
Administrator
Thank you for your time and attention, John. Let me recap to make sure I understand.

I create a plugin.dll.
The CAD calls plugin.dll.
The plugin.dll starts up Squeak.
Squeak then uses FFI to connect to the running plugin.dll.
When the CAD invokes a command to plugin.dll, the plugin.dll passes it to Squeak which then returns the answer via the plugin.dll. This can be repeated indefinitely until program exit.

FYI, I plan to use C# .Net for plugin.dll.

All the best,
Aik-Siong Koh
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

Igor Stasenko
In reply to this post by johnmci
Hello John,
its good that you turned an eye on this problem. :)

I'm also looking for an elegant solution for 'foreign' message sends.

In ideal, i want a following model to work:

- you loading an image in memory.
- interpreter doesn't starts immediately, moreover there is no any
scheduled processed in VM
- a host application then can initiate an evaluation of message by
picking appropriate object(s) which will designate an initial message
send.
- then VM takes resposibility for evaluating the message , and
eventually returns result to caller.

This is what i want from embedded application.
There, of course, many questions and directions to follow, like what
if during evaluation it does [ .. ] fork and then return to caller.

What we should do with forked process, continue running it, or not? If
we suppose that both host application and VM using single thread - it
will unable to run unless host application schedule another message
send to VM. Again, once host app scheduling new message, should it
wait for any forks to complete before starting evaluation of new
message? From host's point of view, it natural, that host expects that
its own requests will be handled as soon as possible regardless of any
other tasks scheduled in VM.

With multiple threads, when host app and VM using separate threads, VM
is free to run own evaluations at any time,  but such model, does not
guarantees that host application request will be handled immediately
(hence the timeouts in your code). Its have to wait until another
Process releasing CPU and/or interrupt occured. For time critical
applications, this is surely could be an issue (but we can ignore it ,
because in the end, its up to developer to choose what things he wants
in image and what's not).

A host application, should be able to control what happens within its
hosted VM, otherwise it can't be seen as embedded application, but
more like separate processes which communicating with each other.

Btw, a remote message send , proposed by Klaus, to
send-a-message-to-another-interpreter-and-wait-result in Hydra is
similar to what you just described. If i remember it correctly, Klaus
calls it SMS.
Its easy to implement and easy to use between interpreters, but for
external host application this is not-so easy, because we don't have
any API for that.

2009/2/8 John M McIntosh <[hidden email]>:

> Ok, let me ramble.
>
> Well in the far past for the macintosh we built a plugin for the browser.
>
> The plugin used the netscape browser api to interface to the netscape and IE
> browser.
> When the plugin was loaded it would set things up, and start running the
> bytecode interpreter.
>
> The VM can be viewed as endless loop, however it is possible to exit the
> loop and return to the caller
> and of course save the interpreter stack state.  Later the caller reenters
> the interpreter loop and continues
> execution.
>
> This logic still exists see
>
> http://isqueak.org/browserPluginReturnIfNeeded
>
> In the early part of the decade I change the logic a bit so that the
> interpreter was spin off as a separate pthread within
> the browser to give us better performance and visual updating.
>
>
> The Hydra VM still exploits this idea of returning from the interpreter loop
> where it does
>
>        lockInterpreter(intr); /* lock interpreter mutex before entering loop
> */
>        while (1)
>        {
>                interpret(intr);
>                // give a chance other threads to do something
>                unlockInterpreter(intr);
>                lockInterpreter(intr);
>                pokeAtTimer(intr);
>                handleEvents(intr);
>        }
>
>
> In this case the interpret() is the endless bytecode interpreter loop, which
> is exited, then the handleEvents
> pulls inter-interpeter events off the queue and we re-enter the interpreter.
>  The other point is the program setups each
> VM on a seperate pthread.
>
>
> The iPhone VM actually runs the VM in a background thread
>
>         // Run the squeak process in a worker thread
>
>        [NSThread detachNewThreadSelector: @selector(runSqueak)
>                                                         toTarget:
>  self.squeakApplication
>                                                   withObject:  NULL];
>
>
> For the current Unix and macintosh browser plugin we take a different
> approach where the plugin launches a separate
> Squeak VM process and uses pipes and shared memory to move items of interest
> between the two process.  So UI gestures enter the browser plugin
> and are sent by a pipe to the squeak process, the squeak process
> interpreters them, and does updates to it's internal Screen. For the unix
> port that's
> a X11 screen hosted by the browser, for the carbon VM it's more complicated
> and has to us a shared memory location and pipe to ask the browser
> plugin to draw the screen within the address space of the browser.   Lastly
> the VM can make requests back to the browser, say to download a file, again
> by sending a message via the pipe.
>
> Astute macintosh folks might note for years now the Squeak carbon app will
> act as a Service, if you have a Squeak image that contains the macintosh
> services logic
> it's possible for you to select smalltalk code in TextEdit, then say
> Services->Squeak DoIt and Squeak will get the services request, do it, and
> return the results.
>
> Now for your problem.
>
>
> (a) You want to run the VM, you can choose to run the VM either as part of a
> currently executing caller thread, or as a pthread, or as a separate
> process.
> (b) You need to choose if you want to start the VM, execute some sort of
> startup script & data, return results, and quit.
> (b) or pass a request to execute something, and return the result somehow.
> There are many ways to do that, file based message passing, pipes, queues,
> shared memory, etc....
>
> The Alien FFI work, or the older FFI logic will help you extract information
> from memory and/or call API routines hosted by the operating system or any
> other loadable DLL.
> The Alien FFI work has logic to let you call back to a squeak method from a
> blocking API call that requires you to provide executable entry points, an
> example given
> is the sort callback where the executable entry point you provide is a
> smalltalk method to compare floating point numbers.
>
>
> What I'd suggest is having your plugin start the VM as a separate pthread
> with a thread safe queue, and location for the squeak external semaphore
> number. Your Squeak image would startup and wait on the semaphore.  Later
> when your CAD system invokes the plugin with lots of parameter data you
> build a queue object, put it on the queue, trigger the squeak semaphore and
> wait.... , once the waiting ends you have someway to pull the results that
> Squeak has made for you, likely populate the queue item with return data,
> and or of course the squeak vm could have manipulated the data to no end.
>
> I'll note for the Objective-C bridge I'm working on for the iPhone has this
> chunk of code below (original donated by Avi)
>
> What happens here is a message send occurs to a squeak proxy object, if the
> message selector is one we
> are interested in we set a pthread conditional lock to :0, then unlock to 1,
> then signal the squeak semaphore.
> the waiting squeak process then locks to condition 1, and the objective C
> code below then attempts an unlock to
> condition 2 and will block as the squeak process runs using the NSInvocation
> instance which contains information
> about the message send, all the parms and has the ability to set the return
> value.  Effectively we have the entire message
> implementation in Smalltalk.  Once the Smalltalk logic completes it unlocks
> condition with condition 2 which lets the  ockWhenCondition: 2
> thus letting the forwardInvocation: terminate.
>
> In this case the SqueakProxy instance is being sent messages on the main
> thread, and the squeak VM is on another thread
> the conditional lock control which thread gets   executed and the invocation
> instance variable is the shared object.
>
> So what about NSDate?   The issue with passing data to complex third party
> is how long do you wait for the third party
> to complete the request. What if your Smalltalk logic is flawed, and you get
> a walkback? Do you wait and time out or
> do you return a bad value event by trapping the unhandled walkback?
>
> - (void) forwardInvocation: (NSInvocation*) anInvocation
> {
>        NSDate *timeout;
>        if (![sigs containsObject: NSStringFromSelector([anInvocation
> selector])]) {
>                return;
>        }
>
>        if([lock lockWhenCondition: 0 beforeDate: (timeout = [[NSDate alloc]
> initWithTimeIntervalSinceNow: 3])])
>        {
>                [lock unlockWithCondition: 1];
>                [timeout release];
>                invocation = [anInvocation retain];
>
>                interpreterProxy->signalSemaphoreWithIndex(sem);
>                if([lock lockWhenCondition: 2 beforeDate: (timeout = [[NSDate
> alloc] initWithTimeIntervalSinceNow: 4])])
>                {
>                        [timeout release];
>                        [invocation release];
>                        [lock unlockWithCondition: 0];
>                }
>                else
>                {
>                        [timeout release];
>                        [invocation release];
>                        [lock unlockWithCondition: 0];
>                }
>        }
>        else
>        {
>                [timeout release];
>                //NSLog(@"failed lock 0");
>        }
> }
>
>
> On 8-Feb-09, at 11:28 AM, askoh wrote:
>
>>
>> For about a year now, I have been asking if Squeak can be called by
>> external
>> programs, if it can be controlled by a non-Squeak program, if it can be
>> used
>> to make plugins or addons in CAD programs. And I have not received an
>> answer
>> that says that it is possible now nor anyone working on that for the
>> future.
>> If Alien FFI can do it I would be most happy to try it immediately. Can
>> the
>> author of Alien FFI give an authoritative answer to its capability to do
>> the
>> above? Is there documentation to describe how? Thanks in advance.
>>
>> All the best,
>> Aik-Siong Koh
>
> --
> ===========================================================================
> John M. McIntosh <[hidden email]>
> Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
> ===========================================================================
>
>
>
>
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

johnmci
In reply to this post by askoh

On 8-Feb-09, at 3:35 PM, askoh wrote:

>
> Thank you for your time and attention, John. Let me recap to make  
> sure I
> understand.
>
> I create a plugin.dll.
> The CAD calls plugin.dll.
> The plugin.dll starts up Squeak.
> Squeak then uses FFI to connect to the running plugin.dll.

Well since you are building a custom VM based dll you can use the  
primitive interface to get at memory within the dll

>
> When the CAD invokes a command to plugin.dll, the plugin.dll passes  
> it to
> Squeak which then returns the answer via the plugin.dll. This can be
> repeated indefinitely until program exit.
>
> FYI, I plan to use C# .Net for plugin.dll.
>
> All the best,
> Aik-Siong Koh
> --
> View this message in context: http://www.nabble.com/Will-Newspeak-be-callable-by-external-programs--tp21896396p21904876.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>
>

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

askoh
Administrator
Your words
"Well since you are building a custom VM based dll you can use the  
primitive interface to get at memory within the dll"
puzzles me. If I use Alien FFI, do I still need to change the VM? Aren't all the changes only in plugin.dll?

Thanks,
Aik-Siong Koh
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

Eliot Miranda-2


On Sun, Feb 15, 2009 at 3:18 PM, askoh <[hidden email]> wrote:

Your words
"Well since you are building a custom VM based dll you can use the
primitive interface to get at memory within the dll"
puzzles me. If I use Alien FFI, do I still need to change the VM? Aren't all
the changes only in plugin.dll?

For callbacks the Alien plugin requires at least a couple of VM methods.  If you're only accessing data or making callouts then it can be made self-contained, but one has to modify the source.

 


Thanks,
Aik-Siong Koh

--
View this message in context: http://www.nabble.com/Will-Newspeak-be-callable-by-external-programs--tp21896396p22029084.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.





Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

johnmci
In reply to this post by askoh
How does the CAD program pass data to a DLL, via a file, via a  
database, via a pipe, via some complex multi-megabyte data structure  
specific to
the Cad vendor for which you hopefully have documentation for.  Once  
you have those magic bits, where do they live, do you make a copy, do
you work with FFI or Alien and poke the bits directly that live in the  
CAD memory space?

Do you copy in to a Smalltalk ByteArray instance and mess with, then  
what do you return to the caller? a number, more data structures, true/
false.

If you have an example CAD to foreign  DLL calling sequence we can  
suggest some solutions.


On 15-Feb-09, at 3:18 PM, askoh wrote:

>
> Your words
> "Well since you are building a custom VM based dll you can use the
> primitive interface to get at memory within the dll"
> puzzles me. If I use Alien FFI, do I still need to change the VM?  
> Aren't all
> the changes only in plugin.dll?
>
> Thanks,
> Aik-Siong Koh
>
> --
> View this message in context: http://www.nabble.com/Will-Newspeak-be-callable-by-external-programs--tp21896396p22029084.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>
>

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

askoh
Administrator
The code below is how C# would call a VisualWorks Smalltalk COM server for motion simulation. I would like C# to call a Squeak motion simulator in a similar fashion. But any workable method would be good too.

I look forward to all suggestions. Squeak can benefit from having the ability to make plugins.

All the best,
Aik-Siong Koh

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CADSM;

public partial class Form1 : Form
    {  
          //Have Added  reference to CADSM, under COM tab.
          //CADSM is actually a tlb, which is registered in the Registry
          //C# program now connects to VisualWorks Smalltalk COM server.
          CADSMClass aCADSMClass = new CADSMClass();
     
        public Form1()
        {
            InitializeComponent();          
           
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Button Click will Trigger the Interaction between CADSM and C# Code
            //Initiate an Assy and assign name and gravity
            CSMAssembly aAssembly = (CSMAssembly)aCADSMClass.AddAssembly();
            aAssembly.Name = "Assembly1";
            double[] aAGravity = {0.0, -9.81, 0.0};
            aAssembly.Gravity = aAGravity;
           
            //Add GlobalOriginMarker to Assy and set marker co-ordinates
            //This is Global Origin Marker
            CSMMarker aGlobalOriginMarker = (CSMMarker)aAssembly.AddMarker();
            aGlobalOriginMarker.Name = "GlobalOriginMarker";
            double[] aGlobalOriginMarkerrFfF = { 0.0, 0.0, 0.0 };
            aGlobalOriginMarker.rFfF = aGlobalOriginMarkerrFfF;
            double[] aGlobalOriginMarkerEulerxyzFf = { 0.0, 0.0, 0.0 };
            aGlobalOriginMarker.EulerxyzFf = aGlobalOriginMarkerEulerxyzFf;
           

            //Initiate a Part and assign name, co-ordinates and Eulers Parameters
            CSMPart aPendulumBlock = (CSMPart)aAssembly.AddPart();
            aPendulumBlock.Name = "PendulumBlock";
            double[] aPendulumBlockrFfF = { 0.0, 0.0, 0.0 };
            aPendulumBlock.rFfF = aPendulumBlockrFfF;
            double[] aPendulumBlockEulerxyzFf = { 0.0, 0.0, 0.0 };
            aPendulumBlock.EulerxyzFf = aPendulumBlockEulerxyzFf;
            double[] aPendulumBlockvOfO = { 0.0, 0.0, 0.0 };
            aPendulumBlock.vOfO = aPendulumBlockvOfO;
            double[] aPendulumBlockOmeOfO = { 0.0, 0.0, 0.0 };
            aPendulumBlock.OmeOfO = aPendulumBlockOmeOfO;

            //Add MassMarker to PendulumBlock
            CSMMassMarker aPendulumBlockMassMarker = (CSMMassMarker)aPendulumBlock.AddMassMarker();
            aPendulumBlockMassMarker.Name = "MassMarker";
            double[] aPendulumBlockMassMarkerrFfF = { 0.5, 0.1, 0.0 };
            aPendulumBlockMassMarker.rFfF = aPendulumBlockMassMarkerrFfF;
            double[] aPendulumBlockMassMarkerEulerxyzFf = { 0.0, 0.0, 0.0 };
            aPendulumBlockMassMarker.EulerxyzFf = aPendulumBlockMassMarkerEulerxyzFf;
            aPendulumBlockMassMarker.Mass = 10.0;
            double[] aPendulumBlockMassMarkerPrincipalInertias = { 0.1, 0.2, 0.3 };
            aPendulumBlockMassMarker.PrincipalInertias = aPendulumBlockMassMarkerPrincipalInertias;

            //Add JointMarker to PendulumBlock
            CSMMarker aPendulumBlockJointMarker = (CSMMarker)aPendulumBlock.AddMarker();
            aPendulumBlockJointMarker.Name = "JointMarker";
            double[] aPendulumBlockJointMarkerrFfF = { 0.1, 0.1, 0.0 };
            aPendulumBlockJointMarker.rFfF = aPendulumBlockJointMarkerrFfF;
            double[] aPendulumBlockJointMarkerEulerxyzFf = { 0.0, 0.0, 0.0 };
            aPendulumBlockJointMarker.EulerxyzFf = aPendulumBlockJointMarkerEulerxyzFf;          


            //Connect the part marker to the ground marker with a joint.
            CSMCylindricalJoint aCylindricalJoint = (CSMCylindricalJoint)aAssembly.AddCylindricalJoint();
            aCylindricalJoint.MarkerI = aGlobalOriginMarker.FullName();
            aCylindricalJoint.MarkerJ = aPendulumBlockJointMarker.FullName();

            //Add a Prescribed Rotational Motion to Joint
            CSMRotationalMotion aMotion1 = (CSMRotationalMotion)aCylindricalJoint.AddRotation();
            aMotion1.Rotation = "2.0*pi*time";

            //Setup Simulation parameters
            CSMSimulation aSimulation = (CSMSimulation)aAssembly.SimulationParameters();
            aSimulation.Tstart = 0.0;
            aSimulation.Tend = 1.0;
            aSimulation.Hout = 0.1;
            aSimulation.Hmin = 1.0e-9;
            aSimulation.Hmax = 1.0;
            aSimulation.ErrorTolerance = 1.0e-6;

            aCADSMClass.StartDynamic();
                       
            //Now, CADSM will start its Dynamic Computations. We need to check the frame and loop through
            // the parts and get their Position details, frame by frame
            //Since we have only one part in this example (PendulumBlock), we just have to get
            // Positional Values, frame by frame.
            //Get Number of Frames from CADSM, this is the first data, we get from CADSM to C#
                        int aNoOfFrames = aCADSMClass.NumberOfFrames();
                       
            //Create an Array to store output data in C#.
                        Array _AllFramesTransformArray = Array.CreateInstance(typeof(Array), aNoOfFrames);
                       
            //Itereate through frames
            short iFrame = 1;
                        while (iFrame <= aNoOfFrames)
            {                
                if (aCADSMClass.CheckFrame(iFrame))
                {                    
                                        Array temp_frameArray = new double[28];                        
                                        CSMPart current_part = aPendulumBlock ;
                                   
                                        //This code gets Position-Velocity-Acceleration data from CADSM
                                        //This needs to be done to every part and every frame..
                                        temp_frameArray = (Array)current_part.Pos4by4VelAccData(iFrame);
                                                           
                    //Set the Array Value to corresponding index
                    AllFramesTransformArray.SetValue(temp_frameArray, iFrame-1);
                    iFrame++;
                }                
            }
                    //Makes a cadsm .asm file for Debug purpose, This will have all the markers and Motion/Forces etc..
                        aAssembly.DebugASM();
            System.Windows.Forms.MessageBox.Show("DebugASM run");
        }
    }
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

Eliot Miranda-2
Koh,

    can you repost putting some markers at the beginning of the lines that actually make the relevant calls to VisualWorks? That would make it much easier to understand.  e.g.
               ...
[1]           aCADSMClass.StartDynamic();
               ...
and then explain each marker, e.g.

[1] call StartDynamic.  This is implemented by the Foo class ...

TIA

On Mon, Feb 16, 2009 at 1:28 PM, askoh <[hidden email]> wrote:

The code below is how C# would call a VisualWorks Smalltalk COM server for
motion simulation. I would like C# to call a Squeak motion simulator in a
similar fashion. But any workable method would be good too.

I look forward to all suggestions. Squeak can benefit from having the
ability to make plugins.

All the best,
Aik-Siong Koh

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CADSM;

public partial class Form1 : Form
   {
         //Have Added  reference to CADSM, under COM tab.
         //CADSM is actually a tlb, which is registered in the Registry
         //C# program now connects to VisualWorks Smalltalk COM server.
         CADSMClass aCADSMClass = new CADSMClass();

       public Form1()
       {
           InitializeComponent();

       }

       private void button1_Click(object sender, EventArgs e)
       {
           // Button Click will Trigger the Interaction between CADSM and
C# Code
           //Initiate an Assy and assign name and gravity
           CSMAssembly aAssembly = (CSMAssembly)aCADSMClass.AddAssembly();
           aAssembly.Name = "Assembly1";
           double[] aAGravity = {0.0, -9.81, 0.0};
           aAssembly.Gravity = aAGravity;

           //Add GlobalOriginMarker to Assy and set marker co-ordinates
           //This is Global Origin Marker
           CSMMarker aGlobalOriginMarker =
(CSMMarker)aAssembly.AddMarker();
           aGlobalOriginMarker.Name = "GlobalOriginMarker";
           double[] aGlobalOriginMarkerrFfF = { 0.0, 0.0, 0.0 };
           aGlobalOriginMarker.rFfF = aGlobalOriginMarkerrFfF;
           double[] aGlobalOriginMarkerEulerxyzFf = { 0.0, 0.0, 0.0 };
           aGlobalOriginMarker.EulerxyzFf = aGlobalOriginMarkerEulerxyzFf;


           //Initiate a Part and assign name, co-ordinates and Eulers
Parameters
           CSMPart aPendulumBlock = (CSMPart)aAssembly.AddPart();
           aPendulumBlock.Name = "PendulumBlock";
           double[] aPendulumBlockrFfF = { 0.0, 0.0, 0.0 };
           aPendulumBlock.rFfF = aPendulumBlockrFfF;
           double[] aPendulumBlockEulerxyzFf = { 0.0, 0.0, 0.0 };
           aPendulumBlock.EulerxyzFf = aPendulumBlockEulerxyzFf;
           double[] aPendulumBlockvOfO = { 0.0, 0.0, 0.0 };
           aPendulumBlock.vOfO = aPendulumBlockvOfO;
           double[] aPendulumBlockOmeOfO = { 0.0, 0.0, 0.0 };
           aPendulumBlock.OmeOfO = aPendulumBlockOmeOfO;

           //Add MassMarker to PendulumBlock
           CSMMassMarker aPendulumBlockMassMarker =
(CSMMassMarker)aPendulumBlock.AddMassMarker();
           aPendulumBlockMassMarker.Name = "MassMarker";
           double[] aPendulumBlockMassMarkerrFfF = { 0.5, 0.1, 0.0 };
           aPendulumBlockMassMarker.rFfF = aPendulumBlockMassMarkerrFfF;
           double[] aPendulumBlockMassMarkerEulerxyzFf = { 0.0, 0.0, 0.0 };
           aPendulumBlockMassMarker.EulerxyzFf =
aPendulumBlockMassMarkerEulerxyzFf;
           aPendulumBlockMassMarker.Mass = 10.0;
           double[] aPendulumBlockMassMarkerPrincipalInertias = { 0.1, 0.2,
0.3 };
           aPendulumBlockMassMarker.PrincipalInertias =
aPendulumBlockMassMarkerPrincipalInertias;

           //Add JointMarker to PendulumBlock
           CSMMarker aPendulumBlockJointMarker =
(CSMMarker)aPendulumBlock.AddMarker();
           aPendulumBlockJointMarker.Name = "JointMarker";
           double[] aPendulumBlockJointMarkerrFfF = { 0.1, 0.1, 0.0 };
           aPendulumBlockJointMarker.rFfF = aPendulumBlockJointMarkerrFfF;
           double[] aPendulumBlockJointMarkerEulerxyzFf = { 0.0, 0.0, 0.0
};
           aPendulumBlockJointMarker.EulerxyzFf =
aPendulumBlockJointMarkerEulerxyzFf;


           //Connect the part marker to the ground marker with a joint.
           CSMCylindricalJoint aCylindricalJoint =
(CSMCylindricalJoint)aAssembly.AddCylindricalJoint();
           aCylindricalJoint.MarkerI = aGlobalOriginMarker.FullName();
           aCylindricalJoint.MarkerJ =
aPendulumBlockJointMarker.FullName();

           //Add a Prescribed Rotational Motion to Joint
           CSMRotationalMotion aMotion1 =
(CSMRotationalMotion)aCylindricalJoint.AddRotation();
           aMotion1.Rotation = "2.0*pi*time";

           //Setup Simulation parameters
           CSMSimulation aSimulation =
(CSMSimulation)aAssembly.SimulationParameters();
           aSimulation.Tstart = 0.0;
           aSimulation.Tend = 1.0;
           aSimulation.Hout = 0.1;
           aSimulation.Hmin = 1.0e-9;
           aSimulation.Hmax = 1.0;
           aSimulation.ErrorTolerance = 1.0e-6;

           aCADSMClass.StartDynamic();

           //Now, CADSM will start its Dynamic Computations. We need to
check the frame and loop through
           // the parts and get their Position details, frame by frame
           //Since we have only one part in this example (PendulumBlock),
we just have to get
           // Positional Values, frame by frame.
           //Get Number of Frames from CADSM, this is the first data, we
get from CADSM to C#
                       int aNoOfFrames = aCADSMClass.NumberOfFrames();

           //Create an Array to store output data in C#.
                       Array _AllFramesTransformArray = Array.CreateInstance(typeof(Array),
aNoOfFrames);

           //Itereate through frames
           short iFrame = 1;
                       while (iFrame <= aNoOfFrames)
           {
               if (aCADSMClass.CheckFrame(iFrame))
               {
                                       Array temp_frameArray = new double[28];
                                       CSMPart current_part = aPendulumBlock ;

                                       //This code gets
Position-Velocity-Acceleration data from CADSM
                                       //This needs to be done to every
part and every frame..
                                       temp_frameArray = (Array)current_part.Pos4by4VelAccData(iFrame);

                   //Set the Array Value to corresponding index
                   AllFramesTransformArray.SetValue(temp_frameArray,
iFrame-1);
                   iFrame++;
               }
           }
                   //Makes a cadsm .asm file for Debug purpose, This will
have all the markers and Motion/Forces etc..
                       aAssembly.DebugASM();
           System.Windows.Forms.MessageBox.Show("DebugASM run");
       }
   }
--
View this message in context: http://www.nabble.com/Will-Newspeak-be-callable-by-external-programs--tp21896396p22046302.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.





Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

askoh
Administrator
Below is the explanation of the C# program in condensed form for easier understanding.
Thanks,
Aik-Siong Koh
---------------------------------
Start the Smalltalk COM Server and returns aCADSMClass intance to C#.
A corresponding aStCADSM object exists in Smalltalk.
    CADSMClass aCADSMClass = new CADSMClass();
Create aStAssembly in Smalltalk and link that to aAssembly in C#.
Send some string and double array values to aAssembly to pass over to aStAssembly.
aStAssembly is contained in aStCADSM.
    CSMAssembly aAssembly = (CSMAssembly)aCADSMClass.AddAssembly();
    ...
Create aStAssemblyMarker in Smalltalk and link that to aGlobalOriginMarker in C#.
aStAssemblyMarker is contained in aStAssembly.
Send some string and double array values to aGlobalOriginMarker to pass over to aStAssemblyMarker.
    CSMMarker aGlobalOriginMarker = (CSMMarker)aAssembly.AddMarker();
    ...
Create aStPart in Smalltalk and link that to aPendulumBlock in C#.
aStPart is contained in aStAssembly.
Send some string and double array values to aPendulumBlock to pass over to aStPart.
    CSMPart aPendulumBlock = (CSMPart)aAssembly.AddPart();
    ...
Create aStPartMarker in Smalltalk and link that to aPendulumBlockJointMarker in C#.
aStPartMarker is contained in aStPart.
Send some string and double array values to aPendulumBlockJointMarker to pass over to aStPartMarker.
    CSMMarker aPendulumBlockJointMarker = (CSMMarker)aPendulumBlock.AddMarker();
    ...
Create aStCylindricalJoint in Smalltalk and link that to aCylindricalJoint in C#.
aStCylindricalJoint is contained in aStAssembly.
Pass the fullname of aGlobalOriginMarker so that aStCylindricalJoint will set aStAssemblyMarker as the Ith marker of aStCylindricalJoint.
Pass the fullname of aPendulumBlockJointMarker so that aStCylindricalJoint will set aStPartMarker as the Jth marker of aStCylindricalJoint.
    CSMCylindricalJoint aCylindricalJoint = (CSMCylindricalJoint)aAssembly.AddCylindricalJoint();
      aCylindricalJoint.MarkerI = aGlobalOriginMarker.FullName();
      aCylindricalJoint.MarkerJ = aPendulumBlockJointMarker.FullName();
Create aStRotationalMotion in Smalltalk and link that to aMotion1 in C#.
aStRotationalMotion is contained in aStAssembly.
Set the equation string for the aStRotationalMotion.
    CSMRotationalMotion aMotion1 = (CSMRotationalMotion)aCylindricalJoint.AddRotation();
      aMotion1.Rotation = "2.0*pi*time";
Create aStSimulationParameters in Smalltalk and link that to aSimulation in C#.
aStSimulationParameters is contained in aStAssembly.
Send some numerical values to aSimulation to pass over to aStSimulationParameters.
    CSMSimulation aSimulation = (CSMSimulation)aAssembly.SimulationParameters();
    ...
Start the dynamic simulation of aStAssembly in aStCADSM. This runs in a separate process from the COM interface process.
    aCADSMClass.StartDynamic();
While the simulation is running aCADSMClass can interrogate if an output frame is ready in the Smalltalk side. If so, aPendulumBlock asks for the simulation output of aStPart sent to it in C# as an array of doubles. The array is accumulated on the C# side for use later or immediately.
    short iFrame = 1;
    while (iFrame <= aNoOfFrames)
    {        
        if (aCADSMClass.CheckFrame(iFrame))
        {    
         Array temp_frameArray = new double[28];        
         temp_frameArray = (Array)aPendulumBlock.Pos4by4VelAccData(iFrame);
         AllFramesTransformArray.SetValue(temp_frameArray, iFrame-1);
    iFrame++;
        }        
    }
When done, quit the COM server and C# can continue without any Smalltalk running.
    aCADSMClass.quit()


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Will Newspeak be callable by external programs?

Bergel, Alexandre
In reply to this post by askoh
Dear Aik-Siong Koh,

Squeak/Pharo has been extended with scripting functionalities. You can  
call Squeak within any bash script.
Please, get in touch with Gwenael to know more about his great work.

Cheers,
Alexandre


On 8 Feb 2009, at 20:28, askoh wrote:

>
> For about a year now, I have been asking if Squeak can be called by  
> external
> programs, if it can be controlled by a non-Squeak program, if it can  
> be used
> to make plugins or addons in CAD programs. And I have not received  
> an answer
> that says that it is possible now nor anyone working on that for the  
> future.
> If Alien FFI can do it I would be most happy to try it immediately.  
> Can the
> author of Alien FFI give an authoritative answer to its capability  
> to do the
> above? Is there documentation to describe how? Thanks in advance.
>
> All the best,
> Aik-Siong Koh
>
>
>
> Michael Haupt-3 wrote:
>>
>> Hi,
>>
>> On Sun, Feb 8, 2009 at 7:43 AM, askoh <[hidden email]> wrote:
>>> Learning from Squeak's mistake,
>>
>> what do you mean?
>>
>>> I am eager to know if Newspeak programs can
>>> be called by external programs. ...
>>
>> I don't quite know if I understand you correctly, but there is a
>> sophisticated FFI implementation (called "Alien FFI") that comes with
>> a robust callback mechanism. So, yes, it is possible to make calls
>> into the image from, e.g., C code. Does that answer your question?
>>
>>> Is there any estimate of a release date?
>>
>> I'm not the one to give a definitive answer here, but Gilad Bracha
>> wrote it would be "Real Soon Now :-)" (capitalised and smileyed as
>> quoted) on January 13th. See
>> http://gbracha.blogspot.com/2009/01/apologia.html
>>
>> Best,
>>
>> Michael
>>
>>
>>
>
> --
> View this message in context: http://www.nabble.com/Will-Newspeak-be-callable-by-external-programs--tp21896396p21902398.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.