Hi Dermot,

Let me try to better explain how blocks are bound...

On Thu, Apr 12, 2012 at 10:22 PM, dermotos <m...@dermotos.com> wrote:

> Im trying to bind the latest version of the bump api (version 3).
> This version uses blocks as callbacks when events occur.
>
> The header file, located here:
> https://github.com/bumptech/bump-api-ios/blob/master/libBump/BumpClient.h
> defines the blocks like this:
>
> /* called after a Bump or No Match is detected. */
> typedef void (^BumpEventBlock)(bump_event event);
>
> /* called after a Match has occurred. */
> typedef void (^BumpMatchBlock)(BumpChannelID proposedChannelID);
>
> /* called after both parties to a Match have confirmed the proposed Channel
> */
> typedef void (^BumpChannelConfirmedBlock)(BumpChannelID channelID);
>
> How do I bind these?
>
> The documentation on this describes how to bind a block like this:
>
> - (void) enumerateObjectsUsingBlock:(void (^)(id obj, BOOL *stop) block
>


Think of the above as a method definition (named
enumerateObjectsUsingBlock) that takes as a parameter an anonymous delegate.

Anonymous "Block" syntax is: <return-type> (^) (<parameter-list>)
<callback-name>

In this case "block" is the callback-name token. This is just the variable
name of the delegate.



>
> like this:
>
> // This declares the callback signature for the block:
> delegate void NSSetEnumerator (NSObject obj, ref bool stop)
>

What the author of the documentation did here was to separate the block
from the method definition so that he could name it.

The above C# delegate maps to: void (^) (id obj, bool *stop);


>
> // Later, inside your definition, do this:
> [Export ("enumerateObjectUsingBlock:")]
> void Enumerate (NSSetEnumerator enum)


> I cant really follow this for the bump binding.
> Does typedef affect how I bind this?
> Do I need to somehow declare BumpChannelConfirmedBlock as a type? how about
> BumpChannelID?
>

BumpChannelIID is defined as: typedef unsigned long long BumpChannelID;

In C#, this would be UInt64 or ulong.

So, if we are to bind the following ObjC blocks;

/* called after a Bump or No Match is detected. */
typedef void (^BumpEventBlock)(bump_event event);

/* called after a Match has occurred. */
typedef void (^BumpMatchBlock)(BumpChannelID proposedChannelID);

/* called after both parties to a Match have confirmed the proposed Channel
*/
typedef void (^BumpChannelConfirmedBlock)(BumpChannelID channelID);


This is what they would look like in C#:

delegate void BumpEventBlock (bump_event event);
delegate void BumpMatchBlock (ulong proposedChannelID);
delegate void BumpChannelConfirmedBlock (ulong channelID);


How do I know to bind them like this? Well, here's what *I* do:

I look at the ObjC definition:

typedef void (^BumpMatchBlock) (BumpChannelID proposedChannelID);

In ObjC, like C and even C#, all typedef does is alias a type. Function
pointers in C and Blocks in ObjC need to be typedef'd if you are going to
use them like "named delegates" (as opposed to anonymous delegates).

So, our revised syntax for named blocks is this:

typedef <return-type> (^<delegate-name>) (<parameter-list>);

Pretty straight forward now, right?

Now it's easy to just do substitution and we get:

delegate void BumpMatchBlock (BumpChannelID proposedChannelId);

Since BumpChannelID maps to a ulong in C#, we can do that substitution and
we end up with:

delegate void BumpMatchBlock (ulong proposedChannelID);


Hope that helps clear things up,

Jeff
_______________________________________________
MonoTouch mailing list
MonoTouch@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/monotouch

Reply via email to