Advertisement

Bind method with this for call as global function in AS

Started by October 26, 2012 11:31 AM
1 comment, last by zerochen 12 years, 1 month ago
The method pointer macros of AS register a class Type and a method. Is it possible to bind a specific instance of a class so that it looks like a global function call from the AS side? I'm currently wrapping the method call inside a global function in such cases and that is OK, but it would be nice to skip that indirection.
There is currently no way to directly register a class method as a global function. The solution that you're already using is the best one at the moment.

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
hi,

i wrote a patch for this some time ago


Index: include/angelscript.h
===================================================================
--- include/angelscript.h (Revision 1359)
+++ include/angelscript.h (Arbeitskopie)
@@ -520,6 +520,7 @@
virtual asIJITCompiler *GetJITCompiler() const = 0;
// Global functions
+ virtual int RegisterGlobalFunction(const char* declaration, const asSFuncPtr &funcPointer, void* obj, asDWORD callConv) = 0;
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv) = 0;
virtual asUINT GetGlobalFunctionCount() const = 0;
#ifdef AS_DEPRECATED
Index: source/as_callfunc.cpp
===================================================================
--- source/as_callfunc.cpp (Revision 1359)
+++ source/as_callfunc.cpp (Arbeitskopie)
@@ -409,12 +409,8 @@
if( callConv >= ICC_THISCALL )
{
- if( objectPointer )
+ if(!((obj = objectPointer) || (obj = descr->GetUserData())))
{
- obj = objectPointer;
- }
- else
- {
// The object pointer should be popped from the context stack
popSize += AS_PTR_SIZE;
Index: source/as_scriptengine.cpp
===================================================================
--- source/as_scriptengine.cpp (Revision 1359)
+++ source/as_scriptengine.cpp (Arbeitskopie)
@@ -2458,6 +2458,83 @@
}
// interface
+int asCScriptEngine::RegisterGlobalFunction(const char* declaration, const asSFuncPtr &funcPointer, void* obj, asDWORD callConv)
+{
+ asSSystemFunctionInterface internal;
+
+ int r = DetectCallingConvention(true, funcPointer, callConv, &internal);
+ if( r < 0 )
+ return ConfigError(r, "RegisterGlobalFunction", declaration, 0);
+
+ if( callConv != asCALL_THISCALL)
+ return ConfigError(asNOT_SUPPORTED, "RegisterGlobalFunction", declaration, 0);
+
+ isPrepared = false;
+
+ // Put the system function in the list of system functions
+ asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
+
+ if( newInterface == 0 )
+ return ConfigError(asOUT_OF_MEMORY, "RegisterGlobalFunction", declaration, 0);
+
+ asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
+
+ if( func == 0 )
+ {
+ asDELETE(newInterface, asSSystemFunctionInterface);
+ return ConfigError(asOUT_OF_MEMORY, "RegisterGlobalFunction", declaration, 0);
+ }
+
+ func->sysFuncIntf = newInterface;
+ func->SetUserData(obj);
+
+ asCBuilder bld(this, 0);
+ r = bld.ParseFunctionDeclaration(0, declaration, func, true, &newInterface->paramAutoHandles, &newInterface->returnAutoHandle, defaultNamespace);
+ if( r < 0 )
+ {
+ // Set as dummy function before deleting
+ func->funcType = asFUNC_DUMMY;
+ asDELETE(func,asCScriptFunction);
+ return ConfigError(asINVALID_DECLARATION, "RegisterGlobalFunction", declaration, 0);
+ }
+
+ // TODO: namespace: What if the declaration defined an explicit namespace?
+ func->nameSpace = defaultNamespace;
+
+ // Check name conflicts
+ r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace);
+ if( r < 0 )
+ {
+ asDELETE(func,asCScriptFunction);
+ return ConfigError(asNAME_TAKEN, "RegisterGlobalFunction", declaration, 0);
+ }
+
+ func->id = GetNextScriptFunctionId();
+ SetScriptFunction(func);
+
+ currentGroup->scriptFunctions.PushLast(func);
+ func->accessMask = defaultAccessMask;
+ registeredGlobalFuncs.PushLast(func);
+
+ // If parameter type from other groups are used, add references
+ if( func->returnType.GetObjectType() )
+ {
+ asCConfigGroup *group = FindConfigGroupForObjectType(func->returnType.GetObjectType());
+ currentGroup->RefConfigGroup(group);
+ }
+ for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
+ {
+ if( func->parameterTypes[n].GetObjectType() )
+ {
+ asCConfigGroup *group = FindConfigGroupForObjectType(func->parameterTypes[n].GetObjectType());
+ currentGroup->RefConfigGroup(group);
+ }
+ }
+
+ // Return the function id as success
+ return func->id;
+}
+
int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv)
{
asSSystemFunctionInterface internal;
Index: source/as_scriptengine.h
===================================================================
--- source/as_scriptengine.h (Revision 1359)
+++ source/as_scriptengine.h (Arbeitskopie)
@@ -100,6 +100,7 @@
virtual asIJITCompiler *GetJITCompiler() const;
// Global functions
+ virtual int RegisterGlobalFunction(const char* declaration, const asSFuncPtr &funcPointer, void* obj, asDWORD callConv);
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv);
virtual asUINT GetGlobalFunctionCount() const;
#ifdef AS_DEPRECATED



example usage:
engine->RegisterGlobalFunction("void Println(const string& in)", asMETHODPR(CScriptFunction, println, (const std::string&), void), this /*pointer to obj of CScriptFunction*/, asCALL_THISCALL);

This topic is closed to new replies.

Advertisement