Jump to content

  • Log In with Google      Sign In   
  • Create Account

- - - - -

Delegates are fully working now


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
13 replies to this topic

#1 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
3Likes
Like

Posted 07 April 2013 - 02:52 PM

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, 07 April 2013 - 03:00 PM.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Sponsor:

#2 saejox   Members   -  Reputation: 714

Like
0Likes
Like

Posted 07 April 2013 - 03:56 PM

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, 07 April 2013 - 04:01 PM.


#3 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
0Likes
Like

Posted 07 April 2013 - 07:01 PM

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.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#4 saejox   Members   -  Reputation: 714

Like
0Likes
Like

Posted 07 April 2013 - 07:59 PM

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

 


   



#5 Jake Albano   Members   -  Reputation: 628

Like
0Likes
Like

Posted 07 April 2013 - 08:23 PM

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. :)



#6 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
0Likes
Like

Posted 08 April 2013 - 08:10 AM

@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.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#7 saejox   Members   -  Reputation: 714

Like
0Likes
Like

Posted 08 April 2013 - 01:37 PM

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.



#8 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
0Likes
Like

Posted 08 April 2013 - 03:54 PM

The scenario should work. The compiler is supposed to pick the right overload. Looks like I missed something. I'll look into it. Thanks.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#9 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
1Likes
Like

Posted 08 April 2013 - 04:02 PM

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.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#10 saejox   Members   -  Reputation: 714

Like
0Likes
Like

Posted 08 April 2013 - 04:45 PM

That works. Thank you.


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

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



#11 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
2Likes
Like

Posted 08 April 2013 - 06:21 PM

I've checked in the fix in revision 1614.

 

I'm glad you like the new features. I'm always trying to improve the library. 

 

By the way, it's now officially 10 years since the first public release of AngelScript biggrin.png Back then the script language only supported 32bit int and float types ph34r.png

 

Regards,

Andreas


Edited by Andreas Jonsson, 08 April 2013 - 06:22 PM.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#12 saejox   Members   -  Reputation: 714

Like
0Likes
Like

Posted 23 April 2013 - 11:07 AM

Hi, its me again :)

 

Will delegates support implicit conversion from functions and methods?

At the moment I'm very conflicted if i should add funcdefs like this: fn_void_int_float .

Because its very hard to remember all those delegate names.
I have less than 10 and still forget the correct one. I do suck at memorizing stuff :D Autocomplete ruined me i guess.



#13 Andreas Jonsson   Moderators   -  Reputation: 3352

Like
0Likes
Like

Posted 23 April 2013 - 02:00 PM

Creating a delegate requires an explicit construct call with the name of the funcdef. I don't plan on having the compiler implicitly create delegates. My recommendation is that you name your funcdef with names that reflect what they meant to be used for, and not their signatures. That ought to make it easier to remember the names :)
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#14 saejox   Members   -  Reputation: 714

Like
0Likes
Like

Posted 23 April 2013 - 03:28 PM

Okay, i understand. Not a big issue. I knew it was far stretch anyways. rolleyes.gif

 

I think i will name them using their signatures.

an example:

AddEvent(FrameEnded, FrameEndedDelegate(func));

but this also has a variant that gives takes a float.

so i need to find another meaningful name. Like

AddEvent(FrameEnded, FrameEndedDelegateWithTimePassed(func));

This gets too complex for my taste. if i were to name it based on signature then i don't need to remember just formulate its name from the signature of the bound function. That function the one she wrote, she can figure delegate name easily.

Another thing when the delegate name is typed wrong since there are too many overloads of the AddEvent resulting error message is not helpful.

One more is that i can generate funcdef declarations using a simple for loop, fn_void_void, fn_void_int, fn_void_float etc... Saves me typing and figuring out clever names for each delegate. Like a poor man's template :P

 

Since, i have no real experience with named delegates. Maybe i will be doing wrong. Time will tell :)






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