Event callbacks can now be transparently added to any C++ member function matching the MicroBitMessageBud signature: void fn(MicroBitEvent e)master
parent
8e1a15c79f
commit
8ea2e953c8
@ -0,0 +1,77 @@
|
||||
#ifndef MEMBER_FUNCTION_CALLBACK_H
|
||||
#define MEMBER_FUNCTION_CALLBACK_H
|
||||
|
||||
#include "mbed.h"
|
||||
#include "MicroBitEvent.h"
|
||||
|
||||
/**
|
||||
* Class definition for a MemberFunctionCallback.
|
||||
*
|
||||
* C++ member functions (also known as methods) have a more complex
|
||||
* representation than normal C functions. This allows a referene to
|
||||
* a C++ member function to be stored then called at a later date.
|
||||
*
|
||||
* This class is used extensively by the MicroBitMessageBus to deliver
|
||||
* events to C++ methods.
|
||||
*/
|
||||
class MemberFunctionCallback
|
||||
{
|
||||
private:
|
||||
void* object;
|
||||
uint32_t method[4];
|
||||
void (*invoke)(void *object, uint32_t *method, MicroBitEvent e);
|
||||
template <typename T> static void methodCall(void* object, uint32_t*method, MicroBitEvent e);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor. Creates a MemberFunctionCallback based on a pointer to given method.
|
||||
* @param object The object the callback method should be invooked on.
|
||||
* @param method The method to invoke.
|
||||
*/
|
||||
template <typename T> MemberFunctionCallback(T* object, void (T::*method)(MicroBitEvent e));
|
||||
|
||||
/**
|
||||
* Comparison of two MemberFunctionCallback objects.
|
||||
* @return TRUE if the given MemberFunctionCallback is equivalent to this one. FALSE otherwise.
|
||||
*/
|
||||
bool operator==(const MemberFunctionCallback &mfc);
|
||||
|
||||
/**
|
||||
* Calls the method reference held by this MemberFunctionCallback.
|
||||
* @param e The event to deliver to the method
|
||||
*/
|
||||
void fire(MicroBitEvent e);
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor. Creates a representation of a pointer to a C++ member function (method).
|
||||
* @param object The object the callback method should be invooked on.
|
||||
* @param method The method to invoke.
|
||||
*/
|
||||
template <typename T>
|
||||
MemberFunctionCallback::MemberFunctionCallback(T* object, void (T::*method)(MicroBitEvent e))
|
||||
{
|
||||
this->object = object;
|
||||
memclr(this->method, sizeof(method));
|
||||
memcpy(this->method, &method, sizeof(method));
|
||||
invoke = &MemberFunctionCallback::methodCall<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template to create static methods capable of invoking a C++ member function (method)
|
||||
* based on the given paramters.
|
||||
*/
|
||||
template <typename T>
|
||||
void MemberFunctionCallback::methodCall(void *object, uint32_t *method, MicroBitEvent e)
|
||||
{
|
||||
T* o = (T*)object;
|
||||
void (T::*m)(MicroBitEvent);
|
||||
memcpy(&m, method, sizeof(m));
|
||||
|
||||
(o->*m)(e);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -0,0 +1,81 @@
|
||||
#ifndef MICROBIT_LISTENER_H
|
||||
#define MICROBIT_LISTENER_H
|
||||
|
||||
#include "mbed.h"
|
||||
#include "MicroBitEvent.h"
|
||||
|
||||
// MessageBusListener flags...
|
||||
#define MESSAGE_BUS_LISTENER_PARAMETERISED 0x0001
|
||||
#define MESSAGE_BUS_LISTENER_METHOD 0x0002
|
||||
#define MESSAGE_BUS_LISTENER_REENTRANT 0x0004
|
||||
#define MESSAGE_BUS_LISTENER_BUSY 0x0008
|
||||
|
||||
struct MicroBitListener
|
||||
{
|
||||
uint16_t id; // The ID of the component that this listener is interested in.
|
||||
uint16_t value; // Value this listener is interested in receiving.
|
||||
uint16_t flags; // Status and configuration options codes for this listener.
|
||||
|
||||
union
|
||||
{
|
||||
void (*cb)(MicroBitEvent);
|
||||
void (*cb_param)(MicroBitEvent, void *);
|
||||
MemberFunctionCallback *cb_method;
|
||||
};
|
||||
|
||||
void* cb_arg; // Optional argument to be passed to the caller.
|
||||
|
||||
MicroBitEvent evt;
|
||||
|
||||
MicroBitListener *next;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a new Message Bus Listener.
|
||||
* @param id The ID of the component you want to listen to.
|
||||
* @param value The event ID you would like to listen to from that component
|
||||
* @param handler A function pointer to call when the event is detected.
|
||||
*/
|
||||
MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent));
|
||||
|
||||
/**
|
||||
* Alternative constructor where we register a value to be passed to the
|
||||
* callback.
|
||||
*/
|
||||
MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent, void *), void* arg);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a new Message Bus Listener, with a callback to a c++ member function.
|
||||
* @param id The ID of the component you want to listen to.
|
||||
* @param value The event ID you would like to listen to from that component.
|
||||
* @param object The C++ object on which to call the event handler.
|
||||
* @param object The method within the C++ object to call.
|
||||
*/
|
||||
template <typename T>
|
||||
MicroBitListener(uint16_t id, uint16_t value, T* object, void (T::*method)(MicroBitEvent));
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a new Message Bus Listener, with a callback to a c++ member function.
|
||||
* @param id The ID of the component you want to listen to.
|
||||
* @param value The event ID you would like to listen to from that component.
|
||||
* @param object The C++ object on which to call the event handler.
|
||||
* @param object The method within the C++ object to call.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
MicroBitListener::MicroBitListener(uint16_t id, uint16_t value, T* object, void (T::*method)(MicroBitEvent))
|
||||
{
|
||||
this->id = id;
|
||||
this->value = value;
|
||||
this->cb_method = new MemberFunctionCallback(object, method);
|
||||
this->cb_arg = NULL;
|
||||
this->flags = MESSAGE_BUS_LISTENER_METHOD;
|
||||
this->next = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Class definition for a MemberFunctionCallback.
|
||||
*
|
||||
* C++ member functions (also known as methods) have a more complex
|
||||
* representation than normal C functions. This allows a referene to
|
||||
* a C++ member function to be stored then called at a later date.
|
||||
*
|
||||
* This class is used extensively by the MicroBitMessageBus to deliver
|
||||
* events to C++ methods.
|
||||
*/
|
||||
|
||||
#include "MicroBit.h"
|
||||
|
||||
/**
|
||||
* Calls the method reference held by this MemberFunctionCallback.
|
||||
* @param e The event to deliver to the method
|
||||
*/
|
||||
void MemberFunctionCallback::fire(MicroBitEvent e)
|
||||
{
|
||||
invoke(object, method, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison of two MemberFunctionCallback objects.
|
||||
* @return TRUE if the given MemberFunctionCallback is equivalent to this one. FALSE otherwise.
|
||||
*/
|
||||
bool MemberFunctionCallback::operator==(const MemberFunctionCallback &mfc)
|
||||
{
|
||||
return (object == mfc.object && memcmp(method,mfc.method,sizeof(method))==0);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Class definition for a MicroBitListener.
|
||||
*
|
||||
* MicroBitListener holds all the information related to a single event handler required
|
||||
* to match and fire event handlers to incoming events.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "MicroBit.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a new Message Bus Listener.
|
||||
* @param id The ID of the component you want to listen to.
|
||||
* @param value The event ID you would like to listen to from that component
|
||||
* @param handler A function pointer to call when the event is detected.
|
||||
*/
|
||||
MicroBitListener::MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent))
|
||||
{
|
||||
this->id = id;
|
||||
this->value = value;
|
||||
this->cb = handler;
|
||||
this->cb_arg = NULL;
|
||||
this->flags = 0;
|
||||
this->next = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a new parameterised Message Bus Listener.
|
||||
* @param id The ID of the component you want to listen to.
|
||||
* @param value The event ID you would like to listen to from that component.
|
||||
* @param handler A function pointer to call when the event is detected.
|
||||
* @param arg An additional argument to pass to the event handler function.
|
||||
*/
|
||||
MicroBitListener::MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent, void *), void* arg)
|
||||
{
|
||||
this->id = id;
|
||||
this->value = value;
|
||||
this->cb_param = handler;
|
||||
this->cb_arg = arg;
|
||||
this->flags = MESSAGE_BUS_LISTENER_PARAMETERISED;
|
||||
this->next = NULL;
|
||||
}
|
||||
|
Loading…
Reference in new issue