Advertisement

Binding classes to use in scripts as value types and by reference?

Started by April 24, 2011 07:46 AM
1 comment, last by duckster 13 years, 7 months ago
Hi there,

I apologise as this does appear to be quite a stupid question, but I'm having a little trouble wrapping my head around the ideal method of binding a class (instantiated in or outside [i.e. in my C++ app] of the script) such that you can pass an instance's pointer to the script (using it by reference; being able to manipulate it directly) and instantiate new instances of the class to be used within the scope of the script.

The only way I can seem to get it working without having to keep specifying everything as a reference (@) is to register my class as a value-type ('Test' in the below example) AND as a reference-type ('refTest').

i.e.
C++

// Instance of Test class instantiated outside of the script, passed by reference to the script
Test *test = new Test("Created outside the script");
ctx->SetArgObject(0, test);
r = ctx->Execute();

test->PrintName();


AS
void main(refTest @obj)
{
Test test("Created inside the script"); // This isn't actually working correctly either (not passing the constructor's args)
obj.PrintName();
test.PrintName();
obj.PrintName("Changed inside the script");
}


Ideally though, I shouldn't need to register everything twice, just specify the @ and let it pass by reference, i.e.:
void main(Test @obj)
{
Test test("Created inside the script"); // This isn't actually working correctly either (not passing the constructor's args)
obj.PrintName();
test.PrintName();
obj.PrintName("Changed inside the script");
}


I guess all I'm asking is, is it possible to bind a class such that you can use it by reference AND as a regular value-type (as in the above example)? Or am I doing things completely wrong? :P
Currently I'm declaring the "two" classes like this:
r = engine->RegisterObjectType("Test", sizeof(Test), asOBJ_VALUE | asOBJ_APP_CLASS_CD);
...
r = engine->RegisterObjectType("refTest", sizeof(Test), asOBJ_REF);


Very new to AngelScript, been over the docs several times in regards to how to go about binding classes/class methods but keep finding samples (not just class binding related) that's no longer usable as methods they use have (long since) been deprecated and removed!

For reference (pun not intended!), the error I'm facing when trying pass my Test instance by reference as the registered "Test" class (value-type) in the script is this:
script.as (1, 16) : ERR : Object handle is not supported for this type
script.as (1, 1) : INFO : Compiling void main(Test)
script.as (1, 16) : ERR : Object handle is not supported for this type


The reason I ask is because it seems a little bit unnecessary having to bind the same class twice, a different way. I have quite a few classes I need to bind, so I don't want to be doing anything at all unnecessary! My current test macro code is looking like:
#define AS_REGISTER_CLASS_METHOD_INTERNAL(C,c,m,p,r) sScriptMgr.GetEngine(ENGINE_AS)->RegisterObjectMethod(C,#r " " #m "(" #p ")",asMETHODPR(c,m,(p),r),asCALL_THISCALL);
#define AS_REGISTER_CLASS_METHOD(c,m,p,r) AS_REGISTER_CLASS_METHOD_INTERNAL(#c,c,m,p,r) \
AS_REGISTER_CLASS_METHOD_INTERNAL("ref" #c,c,m,p,r)
...

AS_REGISTER_CLASS_METHOD(Test,PrintName,void,void)
AS_REGISTER_CLASS_METHOD(Test,ChangeName,string,void)

... so I kind've want to ensure I'm not missing anything important here that I couldn't glean from the docs!


Thanks!
Hi

You can check the 'scriptstring' add-on (not to confuse with 'scriptstdstring'), It registers string as reference type, so you can use handles, but it still can be instantiated inside script (thanks to asBEHAVE_FACTORY, RegisterStringFactory is related to string type only)
Advertisement
Thank you very much! So very simple after all. :)

This topic is closed to new replies.

Advertisement