Jump to content
  • Advertisement
Sign in to follow this  
WitchLord

Delegates are fully working now

This topic is 1858 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've just checked in the last changes to get delegates fully working in the AngelScript library. 

 

If you're interested in trying it out, then you'll need to download revision 1613 from the SVN

 

The solution builds upon the existing function pointers in AngelScript, and the syntax for creating delegates is similar to C#'s delegates.

 

 

class Foo
{
  void Bar() { counter++; }
  void counter = 0;
}
 
 
// Declare a funcdef, which is basically the desired signature for the delegates
funcdef void CALLBACK();
 
void main()
{
  Foo f;
 
  // Create the delegate as a construct call for the funcdef
  // Observe that the single argument gives the object reference and the name of the method
  CALLBACK @callback = CALLBACK(f.Bar);
 
  // Invoke the callback like a normal function
  callback();
}

 

The delegate is an actual object instance, which is slightly different from function pointers to global functions that doesn't create any new object instances. Even so delegates and function pointers are interchangeable as long as the function signature is identical.

 

Delegates cannot be created for value types as the delegate need to be able to hold on to a reference to the object. Currently it is not possible to create delegates for global functions either, but I'll probably have that implemented in the near future.

 

 

 

I hope you like the new enhancement. And please let me know if you find any problems with the implementation, so I can preferably have them fixed before the next release.

 

 

Regards,

Andreas

Edited by Andreas Jonsson

Share this post


Link to post
Share on other sites
Advertisement

Nice.

 

Question:

 

How do i register functions accepting delegates as parameters.

funcdef void CALLBACK();
class Foo
{
  void Bar() { counter++; }
  void counter = 0;
}

events.Add(CALLBACK(f.Bar));

How does RegisterObjectMethod look?

Does it accept asIScriptFunction*? Do i have to increase refcount myself?

Edited by saejox

Share this post


Link to post
Share on other sites
You register it the same way as was done with function pointers before, i.e first register a funcdef to name the callback type, then register the object method as taking a handle of that type.

The method should be implemented to receive a pointer to a asIScriptFunction. The ref count should be updated the same way as is done for any handles.

Share this post


Link to post
Share on other sites

Calling the delegate works. :)

 

Other questions:

asIScriptFunction has objForDelegate but no public method to get it. In some cases i would prefer to hold method pointer and object pointer separately.

 

 

objForDelegate has refCount of 2. Wouldn't it need to be 3? ( gc, script scope, delegate)

class Object
{
  void Method(){}
  int a = 1;
}

int main()
{
  Object @obj = Object();
  GetFunctionPtr(@Callback(obj.Method));
  obj.a++;
  return 1;
}
 

 


   

Share this post


Link to post
Share on other sites

Holy cow, I didn't see this coming for a while yet! Awesome news, Andreas! I think this fulfills the last requirement to make Angelscript my favorite language ever. :)

Share this post


Link to post
Share on other sites
@saejox: I haven't made any interface changes for 2.26.3, but I plan to add methods for inspecting the object pointer and method in 2.27.0. There will also be a new method for creating delegates from the application side. For the refCount, at what exact moment did you inspect the refCount? In the script above, the Object is not garbage collected, so the only references are the local variable and the delegate.

Share this post


Link to post
Share on other sites

Ok, i forgot not all script objects needs to be GC'd. unsure.png

 

 

I have crash during compilation caused by  overloaded methods:

 

class Object
{
  void Method(Object @obj){obj.a++;}
  void Method(){}
  int a = 1;
}

int main()
{
  Object @obj = Object();
  GetFunctionPtr(@Callback(obj.Method));
  obj.a++;
  return 1;
}

 

Registration:

void GetFunctionPtr(asIScriptFunction *func) {...}
r = engine->RegisterFuncdef("void Callback()"); assert(r>=0);
r = engine->RegisterGlobalFunction("void GetFunctionPtr(Callback@)", asFUNCTION(GetFunctionPtr), asCALL_CDECL);
assert(r>=0);

Crashing in module compilation. at line 8122 as_compiler.cpp. bestMethod is null.

Share this post


Link to post
Share on other sites
The scenario should work. The compiler is supposed to pick the right overload. Looks like I missed something. I'll look into it. Thanks.

Share this post


Link to post
Share on other sites
The fix is simple. The if condition on line 8122 needs to check if bestMethod is not null before checking if the constness is correct. I'll have the check-in done as soon as I get home.

Share this post


Link to post
Share on other sites

That works. Thank you.


First multiple subtypes, now delegates. AngelScript started 2013 very strongly.

I need to rewrite significant portion of my game now. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!