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++
#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
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.
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;
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