jweinst1
10/10/2017 - 6:29 AM

new event- reaction programming in cpp

new event- reaction programming in cpp

#include <iostream>

//macro used for dynamically retrieving properties from child classes
#define CHILD_PROP(var, type, prop) (reinterpret_cast<type*>(&var)->prop)


//example for reaction->event based programming

enum EventType
{
  EventType_null,
  EventType_Add,
  EventType_Number,
  EventType_Adder //acts as intermediate between adding a number to another number
};


//base event class
class Event
{
private:
  EventType _type;
public:
  Event(EventType type = EventType_null): _type(type)
  {
    
  }
  
  virtual Event react(Event& event) {}
  
  void setType(EventType type)
  {
    _type = type;
  }
  
  EventType getType() const
  {
    return _type;
  }
  
  static Event null()
  {
    Event n;
    return n;
  }
};


//event number class
class EventNum : public Event
{
private:
  double _value;
public:
  EventNum(double value = 0): _value(value)
  {
    setType(EventType_Number);
  }
  ~EventNum()
  {}
  
  Event react(Event& event);
  
  double& get()
  {
    return _value;
  }
  
  static EventNum make(double value)
  {
    EventNum newnum(value);
    return newnum;
  }
};

//event add class
//doesn't hold data but functions as a convenience class
class EventAdd : public Event
{
public:
 EventAdd()
 {
   setType(EventType_Add);
 }
 ~EventAdd(){}
 
 Event react(Event& event);
 
};

class EventAdder : public Event
{
private:
  double _value;
public:
  EventAdder(double value = 0): _value(value)
  {
    setType(EventType_Adder);
  }
  ~EventAdder()
  {}
  
  double& get()
  {
    return _value;
  }
  
  Event react(Event& event);
  
  static EventAdder make(const double value)
  {
    EventAdder newadd(value);
    return newadd;
  }
};

Event EventNum::react(Event& event)
  {
    switch(event.getType())
    {
      case EventType_Add:
         return EventAdder::make(_value);
         break;
      default:
         return Event::null();
    }
  }
  
Event EventAdd::react(Event& event)
  {
    switch(event.getType())
    {
      case EventType_Number:
         return EventAdder::make(CHILD_PROP(event, EventNum, get()));
         break;
      default:
         return Event::null();
    }
  }
  
Event EventAdder::react(Event& event)
  {
    switch(event.getType())
    {
      case EventType_Number:
         return EventNum::make(_value + CHILD_PROP(event, EventNum, get()));
         break;
      default:
         return Event::null();
    }
  }

int main() {
  EventNum foo = 1;
  EventNum doo = 3;
  std::cout << 'f';
}