cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Events

j o
Associate II

Is there any way to create a custom event, similar to how there are keyboard/touch events?

In my project, I need to have two hardware encoders for user input. Right now, in order to keep the hardware separate from the UI implementation, I have the hardware encoder being polled in a FreeRTOS task and filling a message queue when the encoder value changes. I then read the message queue in the UI task's "tick" loop. Unfortunately, doing this creates a dependency on FreeRTOS, making the simulator unable to compile.

If I could create an additional event type, like an "EncoderEvent", I could have the implementation separate. I've looked at the code for TouchGFX, and it appears that the code I would need to change is only available as a pre-compiled library. Unfortunately, it doesn't even look like it's possible to "create" an event in the present system. When using other graphical libraries, I'm used to seeing a way to post and handle custom events, typically with an enumeration starting at a defined value after all library events, like USER_EVENT_START.

If there is a way to send this data within the design of TouchGFX that I am missing, I would love to know what it is.

Thanks,

Jeremy

1 ACCEPTED SOLUTION

Accepted Solutions
Martin KJELDSEN
Chief III

Just use the ModelListener interface to create your own events.

From e.g. Model::tick() you'll collect whatever state you need to and send out a signal to the active view/presenter using the modelListener interface.

e.g. creating a signal mySignal. All Presenters are ModelListeners and can override the signals declared here.

#ifndef MODELLISTENER_HPP
#define MODELLISTENER_HPP
 
#include <gui/model/Model.hpp>
 
/**
 * ModelListener is the interface through which the Model can inform the currently
 * active presenter of events. All presenters should derive from this class.
 * It also provides a model pointer for the presenter to interact with the Model.
 *
 * The bind function is called automatically.
 *
 * Add the virtual functions Model should be able to call on the active presenter to this class.
 */
class ModelListener
{
public:
    ModelListener() : model(0) {}
 
    virtual ~ModelListener() {}
 
    //empty implementation
    virtual void mySignal(uint8_t _value) {}
 
    /**
     * Sets the model pointer to point to the Model object. Called automatically
     * when switching screen.
     */
    void bind(Model* m)
    {
        model = m;
    }
protected:
    Model* model;
};
 
#endif /* MODELLISTENER_HPP */

From Model.cpp:

void Model::tick()
{
    osEvent event = osMessageGet(GUIevent, 0);  // Get GUIevent immediately
    if (event.status == osEventMessage)
    {
        // handle event
        ControlMessage* message = (ControlMessage*)event.value.p;
        switch (message->messageCode)
        {
            case SYSTEM_ERROR_DETECTED:
                modelListener->myMessage(message->value);
            break;
           ....
        }
    }
}

Then from presenter:

#ifndef MAINPRESENTER_HPP
#define MAINPRESENTER_HPP
 
#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>
 
using namespace touchgfx;
 
class mainView;
 
class mainPresenter : public touchgfx::Presenter, public ModelListener
{
public:
   ...
   virtual void mySignal(uint8_t _value)  
   {
       view->setValue(_value);
    }
 
private:
    mainPresenter();
 
    mainView& view;
};
 
#endif // MAINPRESENTER_HPP

Something like that

/Martin

View solution in original post

3 REPLIES 3
Martin KJELDSEN
Chief III

Just use the ModelListener interface to create your own events.

From e.g. Model::tick() you'll collect whatever state you need to and send out a signal to the active view/presenter using the modelListener interface.

e.g. creating a signal mySignal. All Presenters are ModelListeners and can override the signals declared here.

#ifndef MODELLISTENER_HPP
#define MODELLISTENER_HPP
 
#include <gui/model/Model.hpp>
 
/**
 * ModelListener is the interface through which the Model can inform the currently
 * active presenter of events. All presenters should derive from this class.
 * It also provides a model pointer for the presenter to interact with the Model.
 *
 * The bind function is called automatically.
 *
 * Add the virtual functions Model should be able to call on the active presenter to this class.
 */
class ModelListener
{
public:
    ModelListener() : model(0) {}
 
    virtual ~ModelListener() {}
 
    //empty implementation
    virtual void mySignal(uint8_t _value) {}
 
    /**
     * Sets the model pointer to point to the Model object. Called automatically
     * when switching screen.
     */
    void bind(Model* m)
    {
        model = m;
    }
protected:
    Model* model;
};
 
#endif /* MODELLISTENER_HPP */

From Model.cpp:

void Model::tick()
{
    osEvent event = osMessageGet(GUIevent, 0);  // Get GUIevent immediately
    if (event.status == osEventMessage)
    {
        // handle event
        ControlMessage* message = (ControlMessage*)event.value.p;
        switch (message->messageCode)
        {
            case SYSTEM_ERROR_DETECTED:
                modelListener->myMessage(message->value);
            break;
           ....
        }
    }
}

Then from presenter:

#ifndef MAINPRESENTER_HPP
#define MAINPRESENTER_HPP
 
#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>
 
using namespace touchgfx;
 
class mainView;
 
class mainPresenter : public touchgfx::Presenter, public ModelListener
{
public:
   ...
   virtual void mySignal(uint8_t _value)  
   {
       view->setValue(_value);
    }
 
private:
    mainPresenter();
 
    mainView& view;
};
 
#endif // MAINPRESENTER_HPP

Something like that

/Martin

j o
Associate II

That is how I'm implementing it now, however the model compilation fails on the simulator because it can't include cmsis.os.h:

        Compiling gui/src/containers/SoftButton.cpp
        gui/src/model/Model.cpp:37:10: fatal error: cmsis_os.h: No such file or directory
         #include "cmsis_os.h"
                  ^~~~~~~~~~~~

The way I understand it, the model should be separate from hardware implementation. It's supposed to contain the data to be put on the screen. Requiring the model to have its fingers in the OS breaks abstraction. The ability to send custom events through TouchGFX would alleviate this.

Martin KJELDSEN
Chief III

The simulator obviosuly does not know about an RTOS because it runs on windows. If you have any target specific code you have to do guard it from being read by the windows compiler.

e.g. we expose a symbol SIMULATOR that you can use

#ifndef SIMULATOR
  #include "cmsis_os.h"
#endif