Jump to content

  • Log In with Google      Sign In   
  • Create Account


- - - - -

Bind method with this for call as global function in AS


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 B_old   Members   -  Reputation: 657

Like
0Likes
Like

Posted 26 October 2012 - 05:31 AM

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.

Edited by B_old, 27 October 2012 - 05:46 AM.


Sponsor:

#2 Andreas Jonsson   Moderators   -  Reputation: 3291

Like
0Likes
Like

Posted 26 October 2012 - 07:11 AM

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

#3 zerochen   Members   -  Reputation: 492

Like
0Likes
Like

Posted 27 October 2012 - 11:41 AM

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);




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS