Advertisement

Registering a function to handle a script-specific class

Started by November 20, 2024 02:29 PM
7 comments, last by WitchLord 1 month 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

Ok, that helps. If I do this in the script it compiles the script:

set_message_callback (@handle_my_message);

However, if I do this it will crash in script builder:

set_message_callback (handle_my_message);

So that's an issue in the library.

Right now my C++ code looks like this:

//engine->RegisterFuncdef ("void message_callback(ref @)"); 
engine->RegisterGlobalFunction ("void set_message_callback(ref @)", asFUNCTION (as_set_message_callback), asCALL_CDECL);  

I don't suppose I can tell it to at least constrain the input to a function taking a generic item? I.e. something like this?

engine->RegisterFuncdef ("void message_callback(ref @)"); 
engine->RegisterGlobalFunction ("void set_message_callback(message_callback @)", asFUNCTION (as_set_message_callback), asCALL_CDECL);  

Thanks for your help!

Advertisement

No, unfortunately it is not possible to restrict it like that at this moment.

I'll investigate and fix the crash.

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

I've fixed the issue with the crash in revision 2988.

https://sourceforge.net/p/angelscript/code/2988/

Though. I made a mistake to recommend the use of CScriptHandle. There is no need to use this add-on as you can just as well implement the set_message_callback taking a variable type instead (which is what the CScriptHandle does).

Sorry about that (though it did uncover the bug 🙂)

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

This topic is closed to new replies.

Advertisement