FOnline Development > Questions and Answers
Calling a script from AngelScript
wladimiiir:
Let's say, I have string with the value of "myCoolModule@mySuperCoolFunction". Is there a way how to call the script function that is represented by this value?
I could not find any useful info that this could be done from AngelScript. The only way, which comes to my mind, is to call DLL with C++ function which would call the AngelScript function in return.
Any ideas? Thanks.
Wipe:
Not counting .dlls... hmm, let the workarounds flow~
Server-side you can use time events to run function, with zero delay. Of course, you can't get return value of the function then, plus you'll be limited to int[], uint[], and everything what can be bytepacked as arguments.
Client-side you can use RunServerScriptUnsafe() and pass your string - server's job is to call RunClientScript() using your string as function argument. Same limitations as above.
;D
wladimiiir:
Yeah, I am aware of those options. :)
What I am trying to do is to call fix_ functions in fix_boy.fos, basically, as I am remaking the FixBoy on client side, calling my unsafe_fix functions on server side, which should try to call script functions defined in CraftItem.
So none of this can be used, because they use different arguments. :(
Ghosthack:
Sounds like you have to do a call to a wrapper function with a string argument which can then call the appropriate function, you're able to reduce the amount of boilerplate code by using macros for definitions and calls.
Wipe:
Got bored with own bugs, so why not create some for others :D
--- Code: ---#define valid#(ptr) (@ptr!= null)
funcdef int fixFunc( Critter@ player, int state, CraftItem& craft );
class FixData
{
string Name;
private fixFunc@ func;
FixData( string& name, fixFunc@ func )
{
this.Name = name;
@this.func = func;
}
int Call( Critter@ player, int state, CraftItem& craft )
{
if( valid(func) )
return( func( player, state, craft ));
return( -1 ); // error mark
}
};
array<FixData> Wrapper;
void InitFixboy()
{
Wrapper.insertLast( FixData( "fix_silly", @fix_silly ));
Wrapper.insertLast( FixData( "fix_dummy", @fix_dummy ));
}
int fix_silly( Critter@ player, int state, CraftItem& craft )
{
return( 1207 );
}
int fix_dummy( Critter@ player, int state, CraftItem& craft )
{
return( 1337 );
}
void unsafe_fix( Critter@ player, int craftItem, int state, int, string@ func, array<int>@ )
{
int result = -1; // error mark
if( valid(func) && func.length() > 0 )
{
for( uint w=0, wLen=Wrapper.length; w<wLen; w++ )
{
if( Wrapper[w].Name == func )
{
CraftItem@ craft = GetCraftItem( craftItem );
if( valid(craft) )
result = Wrapper[w].Call( player, state, craft );
break;
}
}
}
Log( "RESULT "+(valid(func)?func:"<invalid>")+":"+result );
if( result == -1 )
{
// error handling
return;
}
// further result processing
}
#ifdef __ASCOMPILER
void test()
{
InitFixboy();
unsafe_fix( null, 0, 0, 0, "fix_silly", null );
unsafe_fix( null, 0, 0, 0, "fix_dummy", null );
unsafe_fix( null, 0, 0, 0, "fix_incorrect", null );
unsafe_fix( null, 0, 0, 0, null, null );
}
#endif
--- End code ---
So yeah, pure AS example; hope it's clear enough for you.
All manual work left is to fill InitFixboy() with all of yours fix_ functions; sadly can't see a way to automate it. I also used Critter@ instead of Critter& for test purposes, so that one need fixing too. Can still be improved, for example by scrapping string@ func usage and relay on CraftItem::Script instead - again, it's done that way or ASCompiler would get mad.
As i understand you want to avoid .dlls [where whole thing would be much easier and shorter] for maximum portability, or is there any other reason?
Navigation
[0] Message Index
[#] Next page
Go to full version