Skip to main content
GameDev.net gamedev.net
🔒 Locked

Squirrel Plus and Polymorphism...

Started by HoteiKid Dec 19, 2005 at 6:48 PM 4 replies 1.8k views
Original Post
HoteiKid
HoteiKid
Hello all, I am trying to replace an already existing Lua scripting system with Squirrel Plus. However, I immediatly encountered some major difficulties. The game engine is set up with an abstract interface. Plugins then provide implementations for those interfaces like in the following:

// Interface (abstract)
class ILight
{
    virtual void doSomething(void) = 0;
};

// In plugin
class OpenGLLight : public ILight
{
    virtual void doSomething(void)
    {
       ...
    }
};
The engine using Luabind binds the abstract interface, not the implementation, and passes instances of the derived classes to the script. In other words:

// Global function that returns instance of a light depending on the plugin loaded
static ILight* CreateLight(void)
{
    if (usingOpenGL)
        return new OpenGLLight;
    ...
}
That function is then binded to Squirrel. And in Squirrel I can then do:

light  = CreateLight();
light.doSomething();
I am lost on how to do this not only in Squirrel but Luabind as well. I would bypass the interfaces completely and bind the implementations but I can't do that with the current engine design. How would I go about doing this? I tried binding the interface but I recieved a "cannot instantiate abstract class" linker error which I expected. How this engine manages to do this with Luabind is a mystery to me. It apperantly uses something called "abstract binder mechanism". I Googled for it and found nothing. Thanks in advance.
fagiano
fagiano
take a look at the DXSquirrel sample in SQPlus. Check the binding for ID3DXMeshBase and ID3DXMesh.

check this out for a non AddRef()/Release() approach:

_MEMBER_FUNCTION_IMPL(BaseLight,constructor){	StackHandler sa(v);	return sa.ThrowError(_T("BaseLight cannot be constructed directly(is pure)"));}_MEMBER_FUNCTION_IMPL(BaseLight,doSomething){	StackHandler sa(v);	_CHECK_SELF(ILight,BaseLight)	self->doSomething(sa.GetInt(2));	return 0;}_BEGIN_CLASS(BaseLight)_MEMBER_FUNCTION(BaseLight,constructor,NULL,NULL)_MEMBER_FUNCTION(BaseLight,doSomething,2,_T("xn")) //takes 2 params (this and a number)_END_CLASS(BaseLight)_IMPL_NATIVE_CONSTRUCTION(OglLight)_MEMBER_FUNCTION_IMPL(OglLight,constructor){	OpenGLLight *newinstace = new OpenGLLight();	//squirrel will automagically call delete the class when needed	return construct_OglLight(newinstace);}_BEGIN_CLASS(OglLight)_MEMBER_FUNCTION(OglLight,constructor,0,NULL)_END_CLASS_INHERITANCE(OglLight,BaseLight)


ciao

Alberto
-----------------------------The programming language Squirrelhttp://www.squirrel-lang.org
HoteiKid
HoteiKid
Ah that looks perfect! I never saw that demo. Thanks for pointing it out. Many thanks.

[Edited by - Zazu on December 20, 2005 9:15:25 PM]
HoteiKid
HoteiKid
Well at first glance it looked perfect. The problem I have however, is that the scripting system is a plugin as well. All of the bindings are in plugins. The binding plugins aren't specific to an implementation since they bind the interface classes only, not the implementation. And the plugins that contain the implementations can't contain any binding code for a specific scripting language. Thats my problem. Well I guess I can sway away from the current way of doing things and make a set of plugins that bind specific implementations to Squirrel, however this means I need to write a binder for every implementation.
fagiano
fagiano
Quote:
Original post by Zazu
Well at first glance it looked perfect. The problem I have however, is that the scripting system is a plugin as well. All of the bindings are in plugins. The binding plugins aren't specific to an implementation since they bind the interface classes only, not the implementation. And the plugins that contain the implementations can't contain any binding code for a specific scripting language. Thats my problem. Well I guess I can sway away from the current way of doing things and make a set of plugins that bind specific implementations to Squirrel, however this means I need to write a binder for every implementation.


Well if the only difference beween implementations is the contructor, then you should just have some function in you plugin to enumerate implementation name and a class factory. you could even have some sort of symbolic way to describe parameters, and pass an array of them to you object factory. Then you can dyncamically inherit from your base class and implement the contructor engine side(the plugin doesn't even have to be dependent on squirrel).

something like
typedef void *(*CONTRUCTOBJECT)(PARAMSARRAY *a);struct AutomationDesc { char *classname; char *basename; ContructionParamsType *params; int nparams; CONTRUCTOBJECT func;}BOOL GetAutomationDesc(AutomationDesc *desc)


just an idea
Alberto
-----------------------------The programming language Squirrelhttp://www.squirrel-lang.org
HoteiKid
HoteiKid
Quote:
Original post by fagiano

Well if the only difference beween implementations is the contructor, then you should just have some function in you plugin to enumerate implementation name and a class factory. you could even have some sort of symbolic way to describe parameters, and pass an array of them to you object factory. Then you can dyncamically inherit from your base class and implement the contructor engine side(the plugin doesn't even have to be dependent on squirrel).

something like
typedef void *(*CONTRUCTOBJECT)(PARAMSARRAY *a);struct AutomationDesc { char *classname; char *basename; ContructionParamsType *params; int nparams; CONTRUCTOBJECT func;}BOOL GetAutomationDesc(AutomationDesc *desc)


just an idea
Alberto



Actually something like this might take place already... I don't really know what those mysterious macros do. I will dig deeper into the macro mechanics today. I am a little confused with the concept of dynamic inherientance in C++, but it may become clearer when I look at the source code. Thanks again.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.