Returning a type which doesn't exist yet (but it will!)

Started by
3 comments, last by LeonMrBonnie 2 years, 5 months ago

Hi all,

I have a C++ GameObject class with a asIScriptObject* member, so each GameObject has the option of running a script. The C++ GameObject class has functions for moving around, rotating, finding other GameObjects in the scene. The AS script class is an abstract class with Create() & Update() functions, called by the C++ GameObject, for behaviour scripts to override. all that stuff is working just fine.

The problem I'm having is that it seems like it'll be a very fundamental feature for scripts to be able to interact with other scripts, but I don't know how to register a method that'll return the script type - here's a cut down example:

// These types are registered before loading the script class, as the script class will use them
engine->RegisterObjectType("GameObject_cpp", 0, asOBJ_REF | asOBJ_NOCOUNT);
engine->RegisterObjectMethod("GameObject_cpp", "Vector3 GetLocalPosition()", asMETHOD(GameObject, GetLocalPosition), asCALL_THISCALL);
// Other position/rotation/scale methods omitted in this example. They've been tested to work, this is just to demonstrate code structure

CScriptBuilder builder;
builder.StartNewModule(engine, "GameEngine");
// The abstract script class is declared in this file as "shared abstract class Script"
builder.AddSectionFromFile("abstract_script.as");

// I hoped this line coming after adding the script section would mean the script type exists, but unfortunately not yet
// This is the problem line. The error is "Identifier 'Script' is not a data type in global namespace" - I presume the type doesn't exist until the module is built?
engine->RegisterObjectMethod("GameObject_cpp", "Script@ GetScript()", asMETHOD(GameObject, GetScriptAddress), asCALL_THISCALL);

// Add scripts which inherit from Script, implementing their own behaviours
for (int i = 0; i < scripts.size(); ++i)
{
builder.AddSectionFromFile(scripts[i].GetFilename());
}

r = builder.BuildModule();

For the GetScript method to be used, it would need to be registered before the derived script classes are built, but it can only be registered after the base script type exists, which seems to happen when the base class is built - at the same time as the derived classes. I think the solution would be either

(a) some way to forward declare the Script type, so it could be used as a return type before being built, or

(b) building the base script class, registering this one method, then building all the derived scripts

Unfortunately I don't know how to do either of those, or whether they're even possible. Any help or advice on this would be greatly appreciated ?

None

Advertisement

For this purpose you would use RegisterInterface. This allows the application to declare a script interface that the script classes must implement in order to be returned from the registered functions.

You can read about this here: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_use_script_class.html#doc_use_script_class_3

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

Thanks so much! Fixed the issue, and much simpler than what I was trying to do.

In case anyone with the same issue stumbles across this post, remember to call AddRef in your equivalent of my GetScriptAddress function! Release will be called when the interface handle goes out of scope, forgetting to add to the counter resulted in the script object being deleted too early. Wondered what was going wrong, totally my mistake there.

None

ChillPenguin said:
In case anyone with the same issue stumbles across this post, remember to call AddRef in your equivalent of my GetScriptAddress function! Release will be called when the interface handle goes out of scope, forgetting to add to the counter resulted in the script object being deleted too early.

Just FYI, you can also add a + to a reference type when it is a return value, and then AngelScript will automatically do the AddRef for you.

So your function signature would look like this then: Script@+ GetScript() and then you can remove your manual AddRef call.

None

This topic is closed to new replies.

Advertisement