//function exported to script void SCSTDCALL Print(Int i) { printf("%d\n", i); }; void main() { ... InitalizeSC(); ... //g_SCEnv is an object achieved with SCInit call ISCType *gns = g_SCEnv->GetGlobalNamespace(); //get global namespace //register s1ns namespace in the global namespace ISCType *scriptNS = SC_NAMESPACE(gns, "s1ns"); if(!scriptNS) return SCTestError("script namespace initialization error", -1); ... }
void main() { ... InitalizeSC(); ... //g_SCEnv is object achieved with SCInit call ISCType *gns = g_SCEnv->GetGlobalNamespace(); ISCType *TByte = SC_SIMPLE_TYPE(gns, Byte); if(TByte == NULL) return SCTestError("type export error", -1); ... }
Simple types may have defined operators.
A default constructor, copy constructor, destructor and assignent operator for non constant arguments are exported when the class is declared, so don't define it again - an error occur
class Soldier { public: Int health; Soldier(Int h) { health = h; } Soldier() { health = 100; } virtual void Hit(Int damage) { health -= damage; } virtual ~Soldier() { } }; Soldier& SCSTDCALL InitSoldier(Soldier &s, Int h) { SC_CONSTRUCTOR_BODY(Soldier, s, (h) ); } void main() { ... InitalizeSC(); ... //g_SCEnv is object achieved with SCInit call ISCType *gns = g_SCEnv->GetGlobalNamespace(); ISCType *tSoldier = SC_BASE_CLASS(gns, Soldier); if(!SC_ATTRIBUTE(tSoldier, Soldier, Int, health) || !SC_CONSTRUCTOR(tSoldier, Soldier, InitSoldier, (Soldier *s, Int h)) || !SC_METHOD(tSoldier, Soldier, void, Hit, (Int damage))) return SCTestError("type export error", -1); ... }
//function exported to script void SCSTDCALL Print(Int i) { printf("%d\n", i); }; void main() { ... InitalizeSC(); ... //g_SCEnv is object achieved with SCInit call ISCType *gns = g_SCEnv->GetGlobalNamespace(); if(!SC_FUNCTION(gns, void, Print, (Int v))) return SCTestError("Print registering error", -1); ... }
... //g_SCEnv is object achieved with SCInit call Int extInt = 10; ISCType *gns = g_SCEnv->GetGlobalNamespace(); ISCSymbol *extIntSym = SC_VARIABLE(gns, Int, extInt);
The first step is to define C++ type by typedef keyword.
typedef void (SCSTDCALL* TFuncVoidInt)(Int x);
Next you must register the function pointer type by using SC_FUNC_PTR_TYPE macro. After that you can use this type is SC code.
ISCType *tTFuncVoidInt = SC_FUNC_PTR_TYPE(globalNS, void, TFuncVoidInt, (Int x)); if(!tTFuncVoidInt) return SCTestError("tTFuncVoidInt export error", -1);
Then you can define a variable in C++ code to hold the SC function pointer. It is treated as a typical variable both on C++ and SC side.
void TestFunc(Int x) { } ... TSCFuncPtr<TFuncVoidInt> funcPtrVoidInt; funcPtrVoidInt = TestFunc; funcPtrVoidInt(10); //calls TestFunc ... funcPtrVoidInt = SC_NULL; //sets pointer to NULL
On SC side you can use TFuncVoidInt type like in the example below.
void SCTestFunc(Int x) { } ... TFuncVoidInt funcPtrVoidInt; scFuncPtrVoidInt = SCTestFunc; scFuncPtrVoidInt(10); //calls SCTestFunc ... scFuncPtrVoidInt = NULL; //sets pointer to NULL
You can also call functions defined in SC code from C++ code by SC function pointers. There are two ways to do that. You can simply export variable and in the script assign to the pointer some function like in the example above. The other way is to use SC_GET_FUNC_PTR macro. It returns a function defined in the script. The call executes the function from the script.
TSCFuncPtrscFunc = SC_GET_FUNC_PTR(script, TFuncVoidInt, "SCTestFunc"); scFunc(10); //calls SCTestFunc
... if(!g_SCEnv->RegisterGlobalAlias("PCStr", "const Char*")) return SCTestError("alias export error", -1); ...