Word from the Author

"One mans mistake is another mans break"
Most of the article(s) which I have posted here are based on my own personal experience. Please do not get aggravated if you disagree with what I wrote.This is just my opinion and it might not be worth much. In case you find some errors or mistakes , have any other useful information which others including myself would benefit from or if you like an article you can always post your messages and comments here.

Event Driven Programming C++ and Delphi

One of the first question which a firmware developer usually asks a desktop developer is about event driven programming since the embedded developer relies heavily on the Controllers ISR (Interrupt Service Routine).

In this post I am going to try to answer this question .The basic idea between event driven programming is almost the same in all programming languages such as Delphi,C++ or C#

Before getting started with an example , I would like to make it clear that there are basically two types of events in an App the first type is the Application Level Events and the other type is System Level Events. In this post I'll only cover Application Level Events.
 
Example of Creating Application Events Directly in C++
In this example whenever the value of variable "i"  in my class is less than 6 an event is triggered.

#define IMPLEMENT_SET_GET_METHOD( type , name ) \
IMPLEMENT_SET_METHOD( type , name );            \
IMPLEMENT_GET_METHOD( type , name );


#define IMPLEMENT_SET_METHOD( type , name )     \
private:                type name;              \
public:                 void set_##name( const type& value ) \
{  name = value;              \
  if(this->Function_Address)  \
  {                           \
   if(value<6){ this->Function_Address(value);}\
  }                           \
}


#define IMPLEMENT_GET_METHOD( type , name )         \
public:          const type& get_##name() const             { return name; }

void myEvent(int iNum)
{
     cout << "Number  less than 6 Event Triggered";
 
}

class MyClass
{
private:
  IMPLEMENT_SET_GET_METHOD(int,i)
  void (*Function_Address)(int);
public:
  MyClass();
  MyClass(void (*iChange)(int));
};

MyClass::MyClass()
{
  this->Function_Address = NULL;
  this->i = NULL;
}

MyClass::MyClass(void (*iChangeHandler)(int))
{
  this->Function_Address = iChangeHandler;
  this->i = 0;
}

void main(void)
{
  MyClass objMyClass(&myEvent);
  objMyClass.set_i(12);
  cin.get();
}

 
Using the Observer Pattern
Now consider the scenario changes and this time you want MyClass to trigger methods of a group of different objects what would you do ?? Well in such a case you'll have to use the observer pattern .In this pattern all the objects that are interested in a specific object  will have to attach themselves to that particular object  hence whenever there is a change in that particular object these attached objects will be informed.


Observer Pattern Example

Now Subject class here is exactly similar to MyClass above.Now if the value of a in this class is less than 6 then an alert is triggered in all of its subscribers
class Subject
{
private:
int a;
std::vector <class Observer*> subscriber;
void update();
public :
   void set_a(int val)
   {
      a = val;
              update();
   }
   void attach(Observer *add)
   {
             subscriber.push_back(add);
   }
};


class Observer
{
private:
Subject *SubjInst;
public:
int object_id;
virtual void mymethod(int id)=0;
  Observer(Subject *sub,int id)
  {
   object_id = id;
   SubjInst = sub ;
   SubjInst->attach(this);
  }
};


void Subject::update()
{
   for(int i=0;i<subscriber.size();i++)
   {
     if(a<6)
     {subscriber[i]->mymethod(subscriber[i]->object_id);}
   }
}
 
class obj1:public Observer
{
public:    
  void mymethod(int id)
  {std::cout << "Object " << id << "Informed" << "\n";}
      obj1(Subject *sub,int id):Observer(sub,id)
      {}
};

void main()
{
//Create a new Subject
Subject some_subject;
obj1 a_object(&some_subject,1);
obj1 b_object(&some_subject,2);
some_subject.set_a(1);
};

Example of Creating Application Events Directly in Delphi
My Delphi is quiet weak now since I no longer use it anymore but I thought that giving a Delphi example would enhance an understanding on events and would serve as a much better example than a plain old simple C#+= example :)

type
  Function_Prototype = procedure(Sender: TObject; Value: Integer) of Object;

  TMyClass = class(TComponent)
  private
     FValue: Integer;
     FEventName: Function_Prototype;  //Step 1:
     procedure SetValue(const AValue: Integer);
     function  GetValue(): Integer;
  public
     constructor Create(AOwner: TComponent); override;
     property Value: Integer read GetValue write SetValue;
  published
     property OnEvent: Function_Prototype read FEventName write FEventName;
  end;

implementation

procedure TMyClass.SetValue(const AValue: Integer);
begin
  FValue := AValue;
  if AValue < 6 then
  begin
    if Assigned(FEventName) then FEventName(Self, Value);
  end;
end;

function TMyClass.GetValue(): Integer;
begin
  Result := FValue;
end;
 

No comments:

Post a Comment