Advertisement

Using classes in angelscript

Started by January 23, 2010 04:35 AM
1 comment, last by AlexanderRieder 15 years, 1 month ago
Hey! I just recently got into angelscript, and after comparing LUA with AS, I finally decided that AS fits better ;D But no post without a problem. I'm trying to make a class in the script and use it in the .cpp files. I've read the docpages about it several times but still can't get it to work. The problem is - I have no idea how to use this function:

SetObject(obj);


From the docs I've read that is should make a new class instance and pass the pointer to the context with this function. But how to make a new class instance? I thought that

int factoryId = type->GetFactoryIdByDecl("MyClass @MyClass()");


Creates a new class instance. But it seems I'm wrong with that. Can somebody please tell me how to use this properly and show me a working example? I'm thankful for each answer. [Edited by - AlexanderRieder on January 26, 2010 3:20:24 AM]
To create a new instance of a script class from the application you first need to know the object type.

Unless you know the name of the class already, you can enumerate the classes that were declared in the script with asIScriptModule::GetObjectTypeCount and GetObjectTypeByIndex. That will let you check the name of the class, and certain properties, e.g. to verify if the class has implemented a specific interface.

Once you have the asIObjectType for the class, you need to determine the id of the factory function that is used to instanciate it. This is done the way you already mentioned.

Then you need to execute the factory function to actually create the instance. This is done like this:

  asIScriptObject *obj = 0;  asIScriptContext *ctx = engine->CreateContext();  ctx->Prepare(factoryFuncId);  int r = ctx->Execute();  if( r != asEXECUTION_FINISHED )  {    // TODO: What should we do in case of error?  }  else  {    obj = *((asIScriptObject**)ctx->GetAddressOfReturnValue());    // Tell AS that we're holding on to the reference    obj->AddRef();  }  ctx->Release();


There is also a short-cut for creating classes, but it is less flexible as you can't send parameters to the factory function:

  int objectTypeId = type->GetTypeId();  asIScriptObject *obj = (asIScriptObject*)engine->CreateScriptObject(objectTypeId);


To call a method on the object instance, you do the following:

  asIScriptContext *ctx = engine->CreateContext();  ctx->Prepare(type->GetMethodIdByDecl("void func()"));  ctx->SetObject(obj);  // TODO: Set any other arguments of the method  int r = ctx->Execute();  if( r != asEXECUTION_FINISHED )  {    // TODO: What should we do in case of error?  }  ctx->Release();


Observe, you'll want to avoid creating and releasing the contexts for each call. Create the context once, and reuse it for each call. You should also cache function ids for functions that are called often.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
Thank you really much!
Now everything works.

This topic is closed to new replies.

Advertisement