Topic: addFunction issue

I have no idea whether this is a bug, or something silly I'm doing.

I have a collection of functions I'm trying to add to lua. As far as I know, I'm registering them correctly:

MEngine* engine = MEngine::getInstance();
MScriptContext* script = engine->getScriptContext();
if(script)
    script->addFunction("broadcastMessage", ScriptBroadcastMessage);

int ScriptBroadcastMessage()
{
    //...
}

I've tried registering the functions on MGame::MGame(), as a static object when the plugin is loaded, and on the first update of MGame. I've checked the value of broadcastMessage from lua on the first update, and on 10th update, and it's always nil.

As I have said, this is probably my fault, but I can't see what I'm doing wrong...

Re: addFunction issue

you should call addFunction in the start plugin call, at the same place you add behaviors.
It's maybe that.

Re: addFunction issue

Behaviours get added automatically with static objects when the plugin is loaded currently, but I'll try adding it to startPlugin later, see if that makes any difference. Thanks

Re: addFunction issue

Nope, that didn't work. It seems to be that at all points where I can realistically put addFunction, it's before the script is initialised

Registering script functions
Starting script
First script update (getBehavior: nil)

The first line is from within the register function that I've been trying to call from various places, the second is from within the script, outside any functions, the last is the first update of the script.

I have no idea why this might be happening, as the MScript setup seems to be that it should add the functions on init(). This is particularly difficult to debug, as I have to build both Maratis, and the game together... I'll see what I can find out

Re: addFunction issue

Other people go out on a Friday night, I sit on a train, coding... or trying to...

Anyway, I've investigated this further. I've finally set up my netbook to easily switch between 3 builds of Maratis (stock distribution, svn dev build and MIngEd dev build) so I can now finally build Maratis and not have to manually copy files over...

Not important. What I have found interesting is that init() is called LONG before the game plugin is loaded... so the reason my functions aren't being found is because it's just being added to the map, but not to the lua_State.

my suggested fix is to change this:

void MScript::addFunction(const char* name, int (*function)(void)){
    m_functions[name] = function;
}

to:

void MScript::addFunction(const char* name, int (*function)(void)){
    m_functions[name] = function;
    if(m_IsRunning)
        lua_register(m_state, name, ::function);
}

I think that should probably fix it. Unfortunately, my train journey is almost over, so I don't think I'll have time...

Re: addFunction issue

It finally occurred to me what's happening.

MScript calls init() on construction, to add all the functions to the lua state. It doesn't call init again unless runScript is called when the script is already running. Therefore, adding functions manually, like I suggested, won't work because it's post-init but pre-run. m_isRunning will be false. The choice then, I think, is either to always call init() on runScript (and not on construction) or to blindly add the function to the lua_State, regardless of whether the script has been initialised, running or whatever. Personally I think the former is best, but I don't know if there was a reason this wasn't done before

Re: addFunction issue

I have just confirmed, for my use case, this definitely fixes the problem. Is it ok to submit this?

Re: addFunction issue

I didn't had time to look at it yet,
the thing is the custom function are in fact not added to the lua state,
so it don't need to be called before init normally, but maybe a bug is there.

If I remember (but I need to check to be sure), custom functions just feed a map used by a special lua function
that itself run the custom function from the map.

Re: addFunction issue

you still need to register MScript::function to respond to the calls from lua (otherwise the symbols are all nil). This is only ever done in MScript::init()

Either MScript::init() needs to be called the first time we run the script (rather than when MScript is initialised), or we manually link MScript::function to the function name in MScript::addFunction. As long as we always add to the map, either way should work, if MScript gets restarted, MScript::init() will then re-link any previously added functions. It's just really a case of whether there was a particular reason MScript::init() was being called on construction, or if it's ok to leave it until we run the script.

Re: addFunction issue

I'm trying to look at it this evening,
I used the system in a work production, so I guess it's more a bug that I added after or something that I moved who broke it.
I'll go back to you, sorry, I'm still not home but in another part of France.

Re: addFunction issue

I think I probably badly tried to optimize the runScript function by adding :

if(m_isRunning)
{
    clear();
    init();
}

it's a mistake as m_isRunning is false the first time it should just be :
clear();
init();

and accessory init() don't need to be called in MScript constructor,
just like you said.

Re: addFunction issue

Ok, I will submit that in a bit. I'm just getting a segfault and I'm trying to figure out where it is. It's only when I call a function I specified... But only after it's already returned to lua... So yeah, no idea what's going on with that right now

Re: addFunction issue

Hi,
I committed a fix, tested on mac with a custom plugin.