C++ – Handling touch detection in iPhone with C++

ccocoa-touchiphone

I'm working on a game for the iPhone, for several reasons most of the code is in C++. I need to write a TouchesManager for my Game, I know about the methods touchesBegan: touchesEnded: and touchesMoved:

I would really like to make a manager in C++ so I can subscribe some classes to this manager, so they can handle touch events in my Game. I have been thinking on making a C++ interface to handle the "touchesBegan: ended: and moved:" that I could implement in the classes I'm interested to respond to touches…

I would really like to know a good simple way this could be achieved, I really need to keep C++ for many reasons ( I love Obj-C / Cocoa-touch, don't get me wrong here please )

Thank you all!

Best Answer

At a higher level, I would create a C++ base class with the exact arguments/names (maybe even self and _cmd). Someplace, you would need to create these, and establish connections from the manager to the objects queried.

The objc objects could either hold a pointer to their C++ implementation/receiver, or you could use an index, or you could use self and a hash/map approach.

So the manager could hold onto a collection of event receivers, and then the UIView would implement the method, which would forward the message to the manager to parse the command (what do you do with the commands/events??).

Alternatively, if all you want is implementation, then just use ObjectiveC++ and add the event receiver/processor as an ivar to the UIResponder.

Addition: Added a quick pseudo-code illustration for 'then just use ObjectiveC++ and add the event receiver/processor as an ivar to the UIResponder'.

// Mr.Gando:
// To answer your question about what do I need to do with events,
// for example I need to subscribe a button to the manager, so when
// it get's touched, a method "Fire" is called... just an example,
// but I think your answer is good. Does this Manager have to be
// thread safe ?

/////////////////////////////////////////////////////////////////////

/* not declared in event_manager_t's scope, so that objc only files may declare members without error - if all your code is objc++, then relocate */
class mon_event_manager_event_handler_t {
/* ... */

    void touchesBegan(id sender, NSSet * touches, UIEvent * event) {
        assert(sender && touches && event);
        assert(this->getResponder() && this->getResponder() == sender);

        if (this->getResponder() && this->getResponder() == sender && this->isSubscribed() && this->isInterestedInTouchesBeganEvents()) {
            SharedEventManager().touchesBegan(this, sender, touches, event);
        }
    }

private:
    UIResponder * responder_;
    UInt32 flags_EventsOrActionsOfInterest_;
    bool isSubscribed_;
};

/** implement as singleton */
class event_manager_t {
/* ... */

    void touchesBegan(handler_t* const handler, id sender, NSSet * touches, UIEvent * event) {
        this->fire();
    }

    void fire() {
        NSLog(@"Fire()");
        /* you can message anything here, just realize that events may not occur on the recipient's work thread */
    }

    static mon_event_manager_event_handler_t* CreateNextHandler(UIResponder * responder) {
    /* SharedEventManager() must guard its data here */
        mon_event_manager_event_handler_t* result(SharedEventManager().createOrReuseHandler());
        result->setResponder(responder);
        SharedEventManager().registerNewHandler(handler);
        return result;
    }

    static void RemoveHandler(mon_event_manager_event_handler_t* handler) {
    /* SharedEventManager() must guard its data here */
        SharedEventManager().removeHandler(handler);
    }

};

/** @return the event_manager_t singleton object */
event_manager_t& SharedEventManager();

/////////////////////////////////////////////////////////////////////

struct mon_event_manager_event_handler_t;

@interface MonResponder
{
    mon_event_manager_event_handler_t* handler_;
}

@end

/////////////////////////////////////////////////////////////////////

@implementation MonResponder

/* ... */

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    assert(handler_ && "TODO: create the handler");
    handler_->touchesBegan(self, touches, event);
    /* ... */
}

@end

/////////////////////////////////////////////////////////////////////