Using Smalltalk as a scripting language

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

Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/30/2009 12:09 AM, Roland Plüss wrote:
> What exactly you mean with "moving"? I'm not referencing to data inside
> the custom data area using pointers. Most of the time I simply store
> there a pointer to the wrapped engine object. Sometimes it's two
> pointers ( required if a non-ref-counted object is stored which is
> located inside a ref-counted object so I store two pointers one with
> ref-counting to guard the second non-ref-counted one ). So as long as
> the data is just copied nothing bad should happen.

Yeah, that's fine.

>> Most likely you'd have a cCall for #initialize
>> anyway.  Having one for #new instead does not change much.
>>
> To my understanding ( from past smalltalk lectures at university where
> we worked with Squeak ) #new is responsible for allocating an object
> while #initialize or #init is responsible for setting up default values
> for the newly created instance. Therefore I proposed #new. Unless that
> is in GST this rule is slightly different.

Yes, my reasoning is: if you used CObject, you would have needed anyway
a cCall to initialize the CObject.  By not using CObject, you just need
your cCall to determine the correct size of the object so you use #new.
  But it's not like one of the two is particularly more hackish.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Using Smalltalk as a scripting language

Roland Plüss-2

>>> Most likely you'd have a cCall for #initialize
>>> anyway.  Having one for #new instead does not change much.
>>>
>> To my understanding ( from past smalltalk lectures at university where
>> we worked with Squeak ) #new is responsible for allocating an object
>> while #initialize or #init is responsible for setting up default values
>> for the newly created instance. Therefore I proposed #new. Unless that
>> is in GST this rule is slightly different.
>
> Yes, my reasoning is: if you used CObject, you would have needed
> anyway a cCall to initialize the CObject.  By not using CObject, you
> just need your cCall to determine the correct size of the object so
> you use #new.  But it's not like one of the two is particularly more
> hackish.
So with other words no damage is done if I hijack #new for the creation
purpose and leaving #initialize to the scripts only for code to setup
their smalltalk type parameters. That sounds good. Let's see if I can
get this one up and kicking. I can't remember of any game project using
smalltalk for scripting. A pity, it's after all the mother of all OO
languages :P ( and a cool language on top of it ).

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/30/2009 06:50 PM, Roland Plüss wrote:
> So with other words no damage is done if I hijack #new for the creation
> purpose and leaving #initialize to the scripts only for code to setup
> their smalltalk type parameters.

Yeah, you can even hijack #basicNew (normally a primitive, but a cCall
is also a "primitive") and do the usual

     new [ ^super new initialize ]

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/30/2009 06:55 PM, Paolo Bonzini wrote:
> On 10/30/2009 06:50 PM, Roland Plüss wrote:
>> So with other words no damage is done if I hijack #new for the creation
>> purpose and leaving #initialize to the scripts only for code to setup
>> their smalltalk type parameters.
>
> Yeah, you can even hijack #basicNew (normally a primitive, but a cCall
> is also a "primitive") and do the usual
>
> new [ ^super new initialize ]

I had a 50% chance of getting it right, and didn't.  I obviously meant

     new [ ^self basicNew initialize ]

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2

>>> So with other words no damage is done if I hijack #new for the creation
>>> purpose and leaving #initialize to the scripts only for code to setup
>>> their smalltalk type parameters.
>>
>> Yeah, you can even hijack #basicNew (normally a primitive, but a cCall
>> is also a "primitive") and do the usual
>>
>> new [ ^super new initialize ]
>
> I had a 50% chance of getting it right, and didn't.  I obviously meant
>
>     new [ ^self basicNew initialize ]
Got stumped :( . I forgot that the class I try to wrap right now is a
singleton. With other words in that case I need to assign a c-pointer
somehow to the class itself not the instance of it. But the class object
is created by smalltalk so I can't mess with it. In fact I need to hack
the class itself since using a cCall #new for an object I need to have
access to the wrapped engine already. Maybe that's not clear. So let's
make an example.

class STSomething which wrapps CSomething.
to create CSomething in c++ land I need a pointer to CEngine in c++
land. But when I assign a cCall for #new in STSomething I do not have
access to the CEngine pointer. For this to work I need the STSomething
class object to store the pointer to the CEngine so that once the cCall
#new is called on STSomething I can create the new object with a brand
new pointer to CSomething.

So basically I need to mess with the STSomething object. Can I do the
same hack you mentioned simply for STSomething like this?

Object subclass: STSomething [
    STSomething class [
        <shape: #byte>
        new [ <cCall: 'CSomething_new' returning: #void args: #(#self)> ]
    ]
]

Or is GST going to whip my ass for that?

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2

> Got stumped :( . I forgot that the class I try to wrap right now is a
> singleton. With other words in that case I need to assign a c-pointer
> somehow to the class itself not the instance of it. But the class object
> is created by smalltalk so I can't mess with it.

No.  Even if it is a singleton, *never* place singleton methods on the
class side.  Add a #uniqueInstance class method cCall and use
gst_register_oop to ensure that the singleton instance is not garbage
collected.

> So basically I need to mess with the STSomething object. Can I do the
> same hack you mentioned simply for STSomething like this?
>
> Object subclass: STSomething [
>      STSomething class [
>          <shape: #byte>
>          new [<cCall: 'CSomething_new' returning: #void args: #(#self)>  ]
>      ]
> ]

I answered above, but probably you want "returning: #smalltalk args:
#(#selfSmalltalk)" in general.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2

>> Got stumped :( . I forgot that the class I try to wrap right now is a
>> singleton. With other words in that case I need to assign a c-pointer
>> somehow to the class itself not the instance of it. But the class object
>> is created by smalltalk so I can't mess with it.
>
> No.  Even if it is a singleton, *never* place singleton methods on the
> class side.  Add a #uniqueInstance class method cCall and use
> gst_register_oop to ensure that the singleton instance is not garbage
> collected.
>
>> So basically I need to mess with the STSomething object. Can I do the
>> same hack you mentioned simply for STSomething like this?
>>
>> Object subclass: STSomething [
>>      STSomething class [
>>          <shape: #byte>
>>          new [<cCall: 'CSomething_new' returning: #void args:
>> #(#self)>  ]
>>      ]
>> ]
>
> I answered above, but probably you want "returning: #smalltalk args:
> #(#selfSmalltalk)" in general.
Okay, this looks a bit more tricky then. I tried now the following but
without any luck so far.

Object subclass: DEEngine [
    DEEngine class [
        | uniqueInstance |
        uniqueInstance [ ^uniqueInstance ]
    ]
    quit [ <cCall: 'stClassEngine.ccQuit' returning: #void args: #(#self)> ]
]

The idea I had is to assign the uniqueInstance instance variable of the
class side from within the c code upon creation time. Doing so the
uniqueInstance would work without having to cCall ( which is a problem
since I would not have an engine pointer at that time ). I did hence the
following:

struct csEngineClass{
    OBJ_HEADER;
    OOP uniqueInstance;
};

// in the creation function
OOP oopClass = gst_class_name_to_oop( "DEEngine" );
csEngineClass *csdata = ( csEngineClass* )OOP_TO_OBJ( oopClass );
csdata->uniqueInstance = pST->CreateNewObject( oopClass );

With CreateNewObject simply creating a new instance of the class. I can
printf csdata->uniqueInstance and it has a proper OOP. When I do though
"DEEngine uniqueInstance printNl" in my script I get nil. Something I
didn't understand on the way you manipulate ST data from C?

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/31/2009 12:18 AM, Roland Plüss wrote:
> Something I didn't understand on the way you manipulate ST data from C?

You forgot the instance variables defined by superclasses of "DEEngine
class".  Better initialize uniqueInstance lazily:

     DEEngine class [
         | uniqueInstance |
         uniqueInstance [ ^uniqueInstance ifNil: [self new] ]
         new [ <cCall: 'DEEngine.new' returning: #smalltalk args: #() ]
     ]

...

     // in the creation function
     OOP oopClass = gst_class_name_to_oop( "DEEngine" );
     deEngine::m_stUniqueInstance = pST->CreateNewObject( oopClass );
     gst_register_oop (deEngine::m_stUniqueInstance);

...

     static OOP deEngine::stNew ()
     {
       return deEngine::m_stUniqueInstance;
     }

...

     gst_define_cfunc ("DEEngine.new", deEngine::stNew);

Nice to see some code in this thread!

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2

>> Something I didn't understand on the way you manipulate ST data from C?
>
> You forgot the instance variables defined by superclasses of "DEEngine
> class".  Better initialize uniqueInstance lazily:
>
>     DEEngine class [
>         | uniqueInstance |
>         uniqueInstance [ ^uniqueInstance ifNil: [self new] ]
>         new [ <cCall: 'DEEngine.new' returning: #smalltalk args: #() ]
>     ]
>
> ...
>
>     // in the creation function
>     OOP oopClass = gst_class_name_to_oop( "DEEngine" );
>     deEngine::m_stUniqueInstance = pST->CreateNewObject( oopClass );
>     gst_register_oop (deEngine::m_stUniqueInstance);
>
> ...
>
>     static OOP deEngine::stNew ()
>     {
>       return deEngine::m_stUniqueInstance;
>     }
>
> ...
>
>     gst_define_cfunc ("DEEngine.new", deEngine::stNew);
>
> Nice to see some code in this thread!
>
Nice try but this won't work. I have an engine pointer and therefore can
not use a singleton in c++ ( although in smalltalk it becomes one ).
Hence I am forced to work without any static class members there. The
only chance I have to get this working is to somehow inject the created
object into the class side variable. This would by itself work if the
oop I assign would actually show up in smalltalk. I don't know yet why
it stays nil. Did I obtain the wrong c pointer? Did I declare the class
side variable incorrectly?

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/31/2009 02:43 AM, Roland Plüss wrote:
> Nice try but this won't work. I have an engine pointer and therefore can
> not use a singleton in c++ ( although in smalltalk it becomes one ).
> Hence I am forced to work without any static class members there. The
> only chance I have to get this working is to somehow inject the created
> object into the class side variable. This would by itself work if the
> oop I assign would actually show up in smalltalk. I don't know yet why
> it stays nil. Did I obtain the wrong c pointer? Did I declare the class
> side variable incorrectly?

No, you declared the Smalltalk struct incorrectly.  If you cannot use a
static class member, use a global variable in the module that implements
the bindings.  I just made it more clever than it needed to be.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2

>> Nice try but this won't work. I have an engine pointer and therefore can
>> not use a singleton in c++ ( although in smalltalk it becomes one ).
>> Hence I am forced to work without any static class members there. The
>> only chance I have to get this working is to somehow inject the created
>> object into the class side variable. This would by itself work if the
>> oop I assign would actually show up in smalltalk. I don't know yet why
>> it stays nil. Did I obtain the wrong c pointer? Did I declare the class
>> side variable incorrectly?
>
> No, you declared the Smalltalk struct incorrectly.
What did I do wrong there?
> If you cannot use a static class member, use a global variable in the
> module that implements the bindings.  I just made it more clever than
> it needed to be.
I didn't state it clearly then. I can not use a static class nor a
static function nor a global variable. The entire engine does not use
globals or singleton by itself. This is what makes it a bit tricky if a
scripting language insists on not storing a user data pointer. So for
example I can have multiple instances of the engine running but each
engine instance has an own scripting environment and inside this
scripting environment the smalltalk class is a singleton. Hence I have
to attach the matching engine pointer to the matching smalltalk
instance. Now I do not plan on using multiple instances but the design
allows for this hence if possible I want to not break it.

Maybe I need to do a hack then by having a class side object which just
holds a pointer ( not the variable itself ). But then I have to provide
a #uniqueInstance: which a stupid developer could break. Not the worst
problem but to my understanding it should be possible to somehow inject
an oop from c++ into smalltalk somehow ( well, except using a #selector:
of course ).

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/31/2009 01:57 PM, Roland Plüss wrote:
>> >  No, you declared the Smalltalk struct incorrectly.
> What did I do wrong there?

You omitted all the variables that are part of every class.  Try "Class
allInstVarNames".

> Maybe I need to do a hack then by having a class side object which just
> holds a pointer ( not the variable itself ).

No, why?

Note that singletons can always be broken.  #initialize can be broken
with #basicNew.  In fact, everything in Smalltalk can be broken, since
there are no private methods.  But I wouldn't worry about that.

Now that I understand more, anyway, I agree that the best thing to do is
what you were doing in the beginning---but with the class variable names
declared correctly based on the output of "Class allInstVarNames".

If you have problems, you can also consider going on the #gnu-smalltalk
IRC channel on freenode.net.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2


>> Maybe I need to do a hack then by having a class side object which just
>> holds a pointer ( not the variable itself ).
>
> No, why?
>
> Note that singletons can always be broken.  #initialize can be broken
> with #basicNew.  In fact, everything in Smalltalk can be broken, since
> there are no private methods.  But I wouldn't worry about that.
I just say "true becomes: false" :P
>
> Now that I understand more, anyway, I agree that the best thing to do
> is what you were doing in the beginning---but with the class variable
> names declared correctly based on the output of "Class allInstVarNames".
How could I forget THAT. Of course I missed the previous instance
variables. I'll change that right away. Sometimes I don't make enough
RTFM :P it looks like.
> If you have problems, you can also consider going on the
> #gnu-smalltalk IRC channel on freenode.net.
>
Came from there to this mailing list as people said it's better here
than there to ask.

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/31/2009 04:17 PM, Roland Plüss wrote:
> Came from there to this mailing list as people said it's better here
> than there to ask.

It depends on the kind of question.  Each has its place. :-)

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2
In reply to this post by Paolo Bonzini-2


> You omitted all the variables that are part of every class.  Try
> "Class allInstVarNames".
>
Okay, I think I know what's the problem. I did the following.

struct csEngineClass{
    OBJ_HEADER;
    OOP uniqueInstance;
};

According to the docs OBJ_HEADER adds all the fields from #Object. This
would be then tough the instance variables of #Object. Is there a macro
for the class side instance variables of Object? Or do I have to make
them on my own ( not a problem by itself ).

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/31/2009 04:22 PM, Roland Plüss wrote:
> Is there a macro
> for the class side instance variables of Object? Or do I have to make
> them on my own ( not a problem by itself ).
>

The latter.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Roland Plüss-2

> On 10/31/2009 04:22 PM, Roland Plüss wrote:
>> Is there a macro
>> for the class side instance variables of Object? Or do I have to make
>> them on my own ( not a problem by itself ).
>>
>
> The latter.
Seems to have done the trick. I'm though not using anymore the macro
approach. I'm a bit allergic against those :P . Looks now like this (
maybe you can add this somewhere to the docs for others if they wanna
use it ).

struct csObject{
    OOP objSize;
    OOP objClass;
};

struct csClassObject : public csObject{
    OOP superclass;
    OOP subClasses;
    OOP methodDictionary;
    OOP instanceSpec;
    OOP instanceVariables;
    OOP name;
    OOP comment;
    OOP category;
    OOP environment;
    OOP classVariables;
    OOP sharedPools;
    OOP securityPolicy;
    OOP pragmaHandlers;
};

Hence I used it now like this:

struct csEngineClass : public csClassObject{
    OOP uniqueInstance;
};

struct csEngine : public csObject{
    /* wrapped c++ data */
};

Now it works and I can inject the uniqueInstance from c++ land.

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://epsylon.rptd.ch/ ,
http://www.moddb.com/games/4057/epsylon )
- Game Engine: Drag(en)gine ( http://dragengine.rptd.ch ,
http://www.moddb.com/engines/9/dragengine )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (269 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Using Smalltalk as a scripting language

Paolo Bonzini-2
On 10/31/2009 04:38 PM, Roland Plüss wrote:
> Looks now like this (
> maybe you can add this somewhere to the docs for others if they wanna
> use it ).
>
> struct csObject{
>      OOP objSize;
>      OOP objClass;
> };

I think I'd use OBJ_HEADER; still here.  But inheritance is a very good
idea for C++, indeed.

Great to hear it works.

For further problems, start a new thread :-)

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
12