Pages: [1]   Go Down
Author Topic: Event Library: clsEvent  (Read 776 times)
0 Members and 1 Guest are viewing this topic.
United kingdom
Offline Offline
Full Member
***
Karma: 1
Posts: 198
just think how much free time you would have if everything worked first time!!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please find below link and source to an event library:
http://avasig.com/clsEvent.zip

Prototype, clsEvent.h
Code:
/**
 * File:
 *  clsEvent.h
 *  
 * Notes:
 *  This file contains the prototype for the class clsEvent.
 *  
 * Methods:
 *  clsEvent      Class constructor
 *  debug         Enable or disable debugging msgs on serial O/P
 *  getName       Returns the name assigned to this event
 *  serviceEvents Should be called in main loop to service events  
 *
 * Members:
 *  m_pTest       Test callback should return true if event should occur
 *  m_pCallback   Call-back routine to call when event test expression is true
 *  m_pData       Data to associate with this instance
 *  m_pstrName    The name assigned to this event
 *  m_pNext       Next event in Linked-list      
 *            
 * History:
 *  29/01/2012  Created by Simon Platten
 */            
#ifndef EVENT_MANAGER_H
  #define EVENT_MANAGER_H
  
  #include <Arduino.h>
  
  class clsEvent {
  private:
    char*     m_pstrName;
    bool      (*m_pTest)(clsEvent* pEvent);
    void      (*m_pCallback)(clsEvent* pEvent);
    void*     m_pData;
    clsEvent* m_pNext;
      
  public:
    static void debug(bool blnDebug);    
    static void serviceEvents();
  
  public:
    clsEvent(char* pstrName,
             bool (*pTest)(clsEvent* pEvent),              
             void (*pCallback)(clsEvent* pEvent),
             void *pData = NULL);
    char* getName();
  };
#endif

Implementation, clsEvent.cpp
Code:
/**                                                                                 /**
 * File:
 *  clsEvent.cpp
 *  
 * Notes:
 *  This file contains the implementation of the class clsEvent.
 *
 * History:
 *  29/01/2012  Created by Simon Platten
 */  
#include "clsEvent.h"
// Pointer to all events linked list
static clsEvent* pAllEvents = NULL;
static bool blnDebugFlag = false;
/**
 * Event constructor
 *  
 * Paramters:
 *  pstrName,   A description of this event
 *  pTest,      callback routine to test if event should occur
 *  pCallback,  the routine to call when the timer expires
 *  pData,      pointer to data block accessible for this timer  
 */        
clsEvent::clsEvent(char* pstrName,
                   bool (*pTest)(clsEvent* pEvent),              
                   void (*pCallback)(clsEvent* pEvent),
                   void *pData) {
// Configure this event
  m_pstrName = pstrName;
  m_pTest = pTest;
  m_pCallback = pCallback;
  m_pData = pData;
  
  if ( pAllEvents != NULL ) {
// Insert this event into the list of all events
    m_pNext = (clsEvent*)pAllEvents;              
  } else {
// This is the first node in the list, ensure that there is no Next node    
    m_pNext = NULL;
  }
// Insert this timer at the beginning of the linked list    
  pAllEvents = this;                    
}
/**
 * Enable or disable debugging msgs on serial O/P
 */
void clsEvent::debug(bool blnDebug) {
  blnDebugFlag = blnDebug;
}
/**
 * Returns the name assigned to this event
 */
char* clsEvent::getName() {
  return m_pstrName;
}
/**
 * Should be called in main loop to service events
 */  
void clsEvent::serviceEvents() {
  for( clsEvent* pEvent=pAllEvents; pEvent!=NULL;
       pEvent=pEvent->m_pNext ) {
    if ( (*pEvent->m_pTest)(pEvent) == true ) {
      if ( blnDebugFlag == true ) {
        Serial.print(pEvent->getName());
        Serial.println(" is true!");
      }    
      (*pEvent->m_pCallback)(pEvent);
    }      
  }
}

The idea behind this class is simple, create your own event using:
Code:
new clsEvent(pstrName, pTest, pCallback, pData);

pstrName is a text string that describes the event, used only when debugging enabled, to show output on serial port
pTest, is a pointer to a test function, prototype: bool (*pTest)(clsEvent* pEvent)
pCallback, is a pointer to a function to call when the result of pTest is true, prototype:  void (*pCallback)(clsEvent* pEvent)
pData, is an option pointer to your own data structure that you can reference via the pEvent pointer passed to your callback.

I am using this to register a test for a push button, the test routine debounces the button and returns true or false, my call back routine then performs an action.

Forgot to mention, you will also need to call the static routine:
Code:
clsEvent::serviceEvents();
From within you loop.
« Last Edit: February 02, 2012, 02:12:30 pm by SPlatten » Logged

Kind Regards,
Sy

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Thanks for sharing!

You might also post one or two demo sketches to "seduce" the customer ... smiley-wink
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

United kingdom
Offline Offline
Full Member
***
Karma: 1
Posts: 198
just think how much free time you would have if everything worked first time!!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Will do, have to wait until tomorrow, on iPad atm
Logged

Kind Regards,
Sy

United kingdom
Offline Offline
Full Member
***
Karma: 1
Posts: 198
just think how much free time you would have if everything worked first time!!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sample sketch...

This just waits for a push button to be pressed then turns on an LED.
Code:
#include <clsEvent.h>

#define PUSH_BUTTON 8
#define MY_LED          13

bool pushButton(clsEvent* pEvent) {
  unsigned long uldTime = 0;    
  while( (digitalRead(PUSH_BUTTON)) == LOW ) {
    if ( uldTime == 0 ) {
// Get reference time
      uldTime = millis();    
    } else if ( (millis() - uldTime) > 200 ) {
// Time expired whilst still high
      return true;
    }
  }
  return false;
}

void swithcOnLED(clsEvent* pEvent) {
  digitalWrite(MY_LED, HIGH);
}

void setup() {  
  pinMode(MY_LED,             OUTPUT);
  pinMode(PUSH_BUTTON,    INPUT);
  digitalWrite(PUSH_BUTTON, HIGH);

  new clsEvent("pbTest", pushButton, swithcOnLED, NULL);
}

void loop() {
// Service any events
  clsEvent::serviceEvents();
// Everything else...
}
Logged

Kind Regards,
Sy

United kingdom
Offline Offline
Full Member
***
Karma: 1
Posts: 198
just think how much free time you would have if everything worked first time!!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Modified class removing debug flag and replacing with DEBUG_EVENTS definition and condition compilation check.
Logged

Kind Regards,
Sy

Pages: [1]   Go Up
Jump to: