Re: Callback Wrapping Help

new topic     » goto parent     » topic index » view thread      » older message » newer message
Icy_Viking said...

Hello all,

I am having trouble wrapping my head around on how to wrap callbacks.

These are function pointer types (mostly use for callbacks, but there are other uses). The asterisk inside the parentheses is part of the type name (because it's a function pointer) not the return value.

typedef size_t (*sfShapeGetPointCountCallback)(void*);        ///< Type of the callback used to get the number of points in a shape 
typedef sfVector2f (*sfShapeGetPointCallback)(size_t, void*); ///< Type of the callback used to get a point of a shape 

This function declaration uses the function pointer types above to take function pointers as a parameter, which it can then use to call that function (hence "callback").

CSFML_GRAPHICS_API sfShape* sfShape_create(sfShapeGetPointCountCallback getPointCount, 
                                           sfShapeGetPointCallback getPoint, 
                                           void* userData); 

First we need to declare sfVector2f struct so FFI knows how to correctly return the value from sfShapeGetPointCallback().

typedef struct { 
    float x; 
    float y; 
} sfVector2f; 

constant SF_VECTOR2F = define_c_struct({ 
    C_FLOAT, -- x 
    C_FLOAT  -- y 
}) 

The we need to declare our own functions that accept the parameters in the typedef's above. I had to dig into the ShapeStruct header to figure out the parameter names and I found some examples demonstrating how to implement custom shapes.

-- Our custom shape data (we can use userData parameter as a shape id). 
-- You could use this approach to define any number of custom shapes. 
sequence sfShapes = { 
    {{-10.0,-10.0},{10.0,-10.0},{10.0,10.0},{-10.0,10.0}} -- a square 
} 
constant SHAPE_SQUARE = 1 -- shape id of the square above 
 
-- Callback that provides the point count of the shape 
function sfShapeGetPointCountCallback( atom userData ) 
 
    atom shapeId = userData -- should be 1 (SHAPE_SQUARE) 
 
    return length( sfShapes[shapeId] ) -- should return 4 
end function 
 
-- Declare the call back with its parameter and return types 
constant sfShapeGetPointCountCallback_cb = call_back( routine_id("sfShapeGetPointCountCallback"), {C_POINTER}, C_SIZE_T ) 
 
-- Callback that provides the points of the shape 
function sfShapeGetPointCallback( atom index, atom userData ) 
 
    atom shapeId = userData -- should be 1 
    atom x = sfShapes[shapeId][1] 
    atom y = sfShapes[shapeId][2] 
 
    return {x,y} -- should return two floats (struct sfVector2f) 
end function 
 
-- Declare the call back with its parameter and return types 
constant sfShapeGetPointCallback_cb = call_back( routine_id("sfShapeGetPointCallback"), {C_SIZE_T,C_POINTER}, SF_VECTOR2F ) 

Then we declare the the function as you did.

constant C_CALLBACK = C_POINTER -- I'm going to add this to std/ffi.e so we can distinguish callbacks from other pointers 
 
constant xsfShape_create = define_c_func(gfx,"+sfShape_create",{C_CALLBACK,C_CALLBACK,C_POINTER},C_POINTER) 
 
public function sfShape_create(atom getPointCount, atom getPoint, atom userData) 
    return c_func(xsfShape_create,{getPointCount,getPoint,userData}) 
end function 

Finally, we would call it like this:

atom shape = sfShape_create( sfShapeGetPointCountCallback_cb, sfShapeGetPointCallback_cb, SHAPE_SQUARE ) 

-Greg

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu