views:

64

answers:

2

Using spacemanager, I need to perform an action on select bodies after each step, so I figured that defining my own C function for iterateFunc would be the way to go.

Everything works great, except I'm not sure how to then call an obj c method in the same class. In other words, an obj c class contains both the c function replacing iterateFunc, and the method that needs to be called. I don't see how to tell the c function what 'self' is, such that I can call the method. As far as i can tell, there's no way to pass in any extra info to the new iterateFunc.

Any ideas, or a better way to go about things?

+1  A: 

Holy vagueness, batman, where's the code snippet? Thankfully, the Magic Powers of Google save the day.

To answer this question requires a few bits of detail:

What is the declaration of iterateFunc?

Oh. It is a cpSpaceHashIterator. Not helpful.

Ah... there it is:

typedef void (*cpSpaceHashIterator)(void *obj, void *data);

It looks like the void *data argument is your answer. Specifically, it looks like that is passed through transparently to your iterator function. That is, if you call:

cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data)

Like this:

cpSpaceEachBody(space, funcPtr, (void *)self);

Then your iterator func could do this:

void iteratorFunc(void *obj, void *data) {
    [(MyClass *)data iterateThis: obj];
}
bbum
Thanks for the input, and you're right, my original was badly lacking in code. Was posting from an iPad, without access to my XCode, and never got around to adding code later. Not helpful for those trying to help me. Sorry about that.To add some code, though, I was thinking exactly what you mentioned, except for the fact that the way one reassigns the iteratorFunc in Spacemanager is through a simple property assingment:smgr.iteratorFunc=doThisFunction;Nowhere to specify arguments or anything. Of course I could subclass, but I was wondering if there were a cleaner way I was missing.
Matt Welch
Need more code; the only spacemanager I find is pure C and maintains the `void*` throughout.... when you say `smgr.iteratorFunc=doThisFunction` what is the context and how is that behavior triggered later?
bbum
A: 

Thx for the response. Declaring a new spacemanager, one can redefine its iterateFunc:

smgr = [[SpaceManager alloc] init];
smgr.iterateFunc=doThisFunc;

In the same class, a "doThisFunc" function can be declared.

In spacemanager, this "iterateFunc" is called from the "step" method:

 -(void) step: (cpFloat) delta
{
.....
    cpSpaceHashEach(_space->activeShapes, _iterateFunc, self);
....
}

So my first thought was to subclass spacemanager, and in my custom step method, call cpSpaceHashEach with my own class, instead of self (the spacemanager, that is). Halfway there, I realized that I didn't even have to do that, as subclassing and defining my own step method was all I needed to do. My new step method:

-(void) step: (cpFloat) delta
{       
    [super step:delta];
    [myObject doThis]; //Having of course set the "myObject" variable elsewhere as my other object
}

Thanks, bbum for both your answers, and for helping me craft better questions in the future.

Matt Welch