Advertisement

Registering a function to handle a script-specific class

Started by November 20, 2024 02:29 PM
4 comments, last by WitchLord 5 hours, 15 minutes ago

I'm trying to get two scripts (on different machines) to communicate, by sending each other structs that are defined by the scripts themselves. To send a struct is easy enough: I declare ‘message’ to be an interface (without any methods, just an interface). A script-class can then just inherit from this interface, and passed to function send(message@) which serializes it and sends it to the other script.

I was hoping to get the other script to register a callback for handling the message, but here I run into a minor problem: if I register a generic handler for ‘message’ I need to cast the message type, which is something I would prefer to avoid, and I have not found a way to allow registration of callbacks that take a script-defined class as an argument. That is, at the time when I try to register the handler, the type being handled must already be known.

In code, the setup:

engine->RegisterInterface ("message");
engine->RegisterGlobalFunction ("void send(message @)", asFUNCTION (HandleSend), asCALL_CDECL);
engine->RegisterFuncdef ("void message_callback(message @)"); 
engine->RegisterGlobalFunction("void set_message_callback(message_callback @)", asFUNCTION (MessageCallback), asCALL_CDECL);  

Shared between scripts:

class my_message: message {
    int int_val = 42;
};

Sending script:

my_message m;
send (m);

This works, because my_message is a message and thus meets the interface requirements.

The receiving script:

void handle_my_message (message @msg) {
    auto @my_msg = cast<my_message> (msg);
    ...do stuff with my_msg...
}
set_message_callback (handle_my_message);

This also works, but requires the cast. Can I somehow do this?

void handle_my_message (my_message @msg) {
    ...do stuff with msg...
}
set_message_callback (handle_my_message);

I prefer the type safety this provides, plus I can then register a message handler for each supported message type, instead of having to figure out the right type at runtime (presumably using some sort of additional identifier). But is it possible?

It's not yet possible to register a ‘forward declaration’ of a script class, or register a function taking a specific script declared class in the signature.

However, you can use the script handle add-on (ref) to store the desired callback and send it to the application. The application can verify if the function signature held in the CScriptHandle is valid and use it as the callback.

The application will need to do the runtime check, but at least the script won't have to.

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

Thanks, that seems like a workable approach.

I seem to have run into a different problem now: I added scripthandle, call RegisterScriptHandle, but as soon as I add any function that takes a ref@ parameter, I get a crash in CScriptBuilder::Build (on the int r = module->Build(); line, suggesting something is wrong with the module pointer, but I can't seem to convince MSVC to actually open the Angelscript symbols file so I can't tell in any more detail. At least ‘this’ seems fine.

RegisterScriptHandle (engine);
…more registrations…
engine->RegisterFuncdef ("void message_callback(message @)"); 
engine->RegisterGlobalFunction("void set_message_callback(ref @)", asFUNCTION (as_set_message_callback), asCALL_CDECL);  

It's the ‘ref @’ in that last line that triggers the problem, if I put it back as it was up above it works fine.

That sounds like your build might have gotten corrupt. Try do a clean build.

I don't see anything wrong with the snippet you posted.

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

Try adding the @ symbol when sending the function pointer to the set_message_callback.

set_message_callback (@handle_my_message);

Of course, if this is really the cause of the crash it would be a bug in AngelScript, but it might work until I get a chance to investigate it further.

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