|
The **Active Object** design pattern decouples method execution from method invocation.
|
|
The **Active Object** design pattern decouples method execution from method invocation.
|
|
An active object is an object that "runs" in a *separate thread*.
|
|
An active object is an object that "runs" in a *separate thread*.
|
|
|
|
|
|
It can be useful for in a situation in which an object has to periodically pop elements from a queue, which are in turn produced by a second thread or for example for a receiver object that has to continuously check for incoming messages.
|
|
It can be useful for in a situation in which an object has to periodically pop elements from a queue, which are in turn produced by a second thread or for example for a receiver object that has to continuously check for incoming messages.
|
|
|
|
|
|
## Methods
|
|
In `src/shared/` you can find the corresponding template.
|
|
|
|
|
|
In `src/shared/` you can find the corresponding template.
|
|
## Implementation
|
|
The most relevant functions are:
|
|
The most relevant functions are:
|
|
- **Constructor**: creates a Miosix Thread.
|
|
- **virtual bool start()**: creates a Miosix Thread, which in turn call *threadLauncher()*. It returns a bool indicating whether the thread was correctly created or not.
|
|
- **threadLauncher**: private static function that is executed from the Thread, calls the run() method.
|
|
- **virtual void stop()**: stop the ActiveObject's and join its thread.
|
|
- **run**: protected method, should be overridden with the code that you want to run on the Thread.
|
|
- **static void threadLauncher(void\* arg)**: private static function that is executed from the thread, which in turn calls the *run()* method.
|
|
|
|
- **virtual void run()**: protected method, should be overridden with the code that you want to run in the thread.
|
|
In order to start the active object you can call `start()` while you can call `stop()` in order to stop it.
|
|
|
|
|
|
|
|
## Example
|
|
## Example
|
|
|
|
|
... | @@ -21,15 +20,17 @@ In order to start the active object you can call `start()` while you can call `s |
... | @@ -21,15 +20,17 @@ In order to start the active object you can call `start()` while you can call `s |
|
* module and forwards an event to the EventBroker accordingly to the received
|
|
* module and forwards an event to the EventBroker accordingly to the received
|
|
* message.
|
|
* message.
|
|
*/
|
|
*/
|
|
class Receiver : ActiveObject {
|
|
class Receiver : ActiveObject
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
public:
|
|
/* Constructor: sets the RF driver to use */
|
|
/* Constructor: sets the RF driver to use */
|
|
Receiver(Gamma868* gamma) {
|
|
Receiver(Gamma868* gamma)
|
|
|
|
{
|
|
this->gamma = gamma;
|
|
this->gamma = gamma;
|
|
}
|
|
}
|
|
|
|
|
|
/* Deconstructor */
|
|
/* Destructor */
|
|
~Receiver() {}
|
|
~Receiver() {}
|
|
|
|
|
|
protected:
|
|
protected:
|
... | @@ -37,10 +38,12 @@ protected: |
... | @@ -37,10 +38,12 @@ protected: |
|
* Function executed in a separate thread: waits for a packet and forwards
|
|
* Function executed in a separate thread: waits for a packet and forwards
|
|
* the corresponding event.
|
|
* the corresponding event.
|
|
*/
|
|
*/
|
|
void run() {
|
|
void run() override
|
|
|
|
{
|
|
// Infinite loop
|
|
// Infinite loop
|
|
while(1) {
|
|
while(1)
|
|
// Do stuff
|
|
{
|
|
|
|
... // do stuff
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
... | @@ -48,4 +51,21 @@ private: |
... | @@ -48,4 +51,21 @@ private: |
|
Gamma868* gamma;
|
|
Gamma868* gamma;
|
|
|
|
|
|
};
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
And in the main:
|
|
|
|
```cpp
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
Receiver rec(new Gamma868(...));
|
|
|
|
|
|
|
|
if (rec.start())
|
|
|
|
{
|
|
|
|
... // do stuff
|
|
|
|
|
|
|
|
rec.stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
``` |
|
``` |
|
|
|
\ No newline at end of file |