Advertisement

Copying a script object in C++

Started by February 06, 2025 04:09 PM
4 comments, last by WitchLord 1 week, 6 days ago

I've declared an object type in AS:

class MyMsg : IMessage
{
    int iValue = 0;
}

IMessage is just an empty interface. Now I want to send that message to another object with a delay:

MyMsg msg;
msg.iValue = 42;
GetObject().PostMessage(msg, 0.5);

PostMessage is implemented on the C++ side and now needs to duplicate the object, so that it can return to the script and let msg get destroyed, because it was created on the stack.

The function is registered like this:

RegisterObjectMethod("GameObject", "void PostMessage(const ezAngelScriptMessage& in, float delay)", asFUNCTION(GameObject_PostMessage), asCALL_GENERIC));

Now I wanted to use asCScriptEngine::CreateScriptObjectCopy to make a copy, but it always returns nullptr. The documentation says “This only works for objects, for primitive types and object handles the method doesn't do anything and returns a null pointer.” However, as far as I understand it, this IS an object, not a handle.

I've even tried this, to “fix” the type;

auto pArgType = pGen->GetEngine()->GetTypeInfoById(pGen->GetArgTypeId(0));
const char* szTypeName = pArgType->GetName();
auto pArgType2 = pGen->GetEngine()->GetTypeInfoByName(szTypeName);
void* pMsgCopy = pGen->GetEngine()->CreateScriptObjectCopy(pAsMsg, pArgType2);

The two types are different, so something is going on, but even with the second type, it doesn't work.

Stepping through the code, it ultimately ends up in asCScriptEngine::CreateScriptObject where it fails because objType->beh.factory == 0.

I don't get, why there shouldn't be a factory for this? I can instantiate other classes that are declared in scripts, without anything else declared (constructor or so).

Any idea what might be the problem?

It looks like you're trying to make a copy of ezAngelScriptMessage (since you're getting the type of the argument). Instead get the type of the actual object you received, and make a copy for that type.

void* pMsgCopy = pGen->GetEngine()->CreateScriptObjectCopy(pAsMsg, (reinterpret_cast<asIScriptObject*>(pAsMsg)->GetObjectType());

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

Ok, that kinda makes sense, I guess, what I tried to use was just the function signature type, not the actual type of the incoming object.

Anyway, at first this only brought me one step further. It now created another message object, but then the entire script gets just interrupted.

Stepping through this, in CreateScriptObjectCopy it reaches the final else clause, then executes CreateScriptObject successfully, but then fails in AssignScriptObject with "Cannot do value assignment" and then returns asNOT_SUPPORTED.

After some investigation, I figured that I had asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE enabled. Disabling that again, it now works as desired.

Disabling asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE now has the side-effect that in many scripts I just passed handles to functions that take handles as out parameters, without writing the @ in front there, which is now a compiler error.

I'm not sure whether that is a good thing or not. If I have a handle and a function takes a handle, I don't understand why I need to add the @ and what could happen if I don't do that.

So I'm also wondering whether I can have the implicit copy behavior in this case, but disable it for specific types, rather than globally.

The @ symbol is included on expressions to indicate that you want to work on the address, rather than the object that the address is referring to.

If you don't want the value assignment operator on select classes, you can ‘delete’ the opAssign operator, e.g.

 class MyClass
  {
        MyClass &opAssign(const MyClass &inout) delete;
  }

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