I am refactoring some code to decouple GUI from some state.
#include <StateObject>
Class GUI{
...
StateObject A;
void doSomething() { A->hullaballoo();}
**void ReFreshMyGui() { //take state A and redraw }**
};
State object is being shared by multiple classes to update the state but this Gui Object specializes in displaying the state. So I would like to call the Refresh function via StateObject whenever its modified.
I am not sure how or if signals will provide the solution. Any hints?
In order to decouple GUI and Data you could use the MVC pattern. This means your GUI should register to your model's (data) object(s) and whenever the data changes the GUI will be notified and it will be the GUI to redraw itself.
But careful, the model should not have the notion of a concrete GUI, instead the GUI should implement an observer interface containing a method (e.g. void Update()) that will be called whenever changes occur (notification handler).
Just look for the MVC-pattern on google. You'll find thousands of useful tutorials.
You may also take in consideration the MVP and the MVVM patterns.
Example:
class Observer
{
virtual void Update(void* data) = 0;
}
class GUI : public Observer
{
public:
virtual void Update(void* data)
{
//Redraw method and some other things you may
//want to do with the new data
}
}
class Model
{
private:
int m_iData;
List<Observer> observers;
public:
void SetData(int iData)
{
m_iData = iData;
for(int i = 0; i < observers.Length; i++)
{
observers[i].Update(NULL);
}
}
}
Related
I have an Event system in which a Manager class contains a queue of Events. The Event class is currently an abstract base class from which all specific events are derived. The idea is to allow the Manager to process() specific events that are specialized classes constructed with their own, unique parameters elsewhere in the code where the context of creation informs which event to create and how (sometimes using an Abstract Factory pattern). These Events are consumed asynchronously by Manager in a loop that continuously empties the queue, processing each event, and then destroying it as it is popped.
I designed this system to alleviate Manager from doing all of its own data manipulation. Instead, other parts of the code can queue an Event object, and that object can perform a task via its process() member, with the Manager not needing to know about it in detail.
Without an encapsulated Event system, I would be making endless additions to Manager's members: one for each task, and calling those tasks in case statements somewhere, which is terrible. I thought it would be better to use the Event system I have in the example here. This leaves Manager unchanged while various derived, specific events are defined elsewhere. This minimal example works fine, but the problem is that all derived Events need access to Manager's private data for each one's process() to have full capability as intended. If friend inheritance was allowed, simply making Event a friend class of Manager would solve the problem. Since it's not, the only way for this to work is to make all of Manager's data public (or, technically, add every new derived Event class I make as a friend to Manager).
This works, but feels wrong, and makes me think this is not the correct design. To be clear, the Manager contains a good deal of centralized information (necessary for thread sync, etc) that is more extensive than the Example would indicate. It manages network connections that will spawn a variety of different, often arbitrary events. I'd like to elegantly react to such an environment without inflating Manager with endless additional member functions every time I want to create a new type of event.
Is there a better way to achieve this code separation pattern and still retain the freedom I want for the separated code? Should I just publicize all of Manager's data after all?
The minimal Example (includes pseudocode):
class Event;
class Manager
{
public:
Manager() {}
// Event queue insertion and processing functions omitted
// private: // Commented out on purpose to allow compilation
int dataInt;
double dataReal;
std::string dataStr;
std::queue<Event *> events;
};
// Abstract Event base class with process() member
class Event
{
public:
Event(Manager * m) : manager(m)
{
process = std::bind(&Event::processKernel, this);
}
// Process the event
std::function<void(void)> process;
protected:
// Actual processing code: derived classes must define this function
virtual void processKernel() = 0;
private:
Manager * m;
};
// One example of a specialized (derived) Event
class SpecificEvent: public Event
{
public:
SpecificEvent(Manager * m, int p) : Event(m), param(p) { }
void processKernel()
{
// Intention: modify parent manager data
manager->dataInt = param;
}
private:
int param;
};
// Another specialized (derived) Event
class OtherEvent: public Event
{
public:
OtherEvent(Manager * m, double p) : Event(m), param(p) { }
void processKernel()
{
// Intention: modify parent manager data
manager->dataReal = param;
}
private:
double param;
};
// Example usage: could be inside a Manager member, or anywhere else
int main()
{
Manager manager;
// Make a SpecificEvent, pass it the manager, and its own specific parameter(s)
SpecificEvent e(&manager, 10);
//<Not shown> Add to manager's queue
// Manager processes this event at some point later with Event::process()
}
Since
If friend inheritance was allowed, simply making Event a friend class
of Manager would solve the problem
you can just get away with
struct ManagerFields { // all Manager's fields; just for the further convenience
int dataInt;
double dataReal;
};
class Manager: private ManagerFields { // only Manager and its friends know these Fields
friend class Event;
// here Manager can use dataInt, dataReal etc. just like before
};
class Event {
public:
Event(Manager* m) : manager{m} {}
virtual void process() = 0;
protected: // "friend inheritance" setup below
ManagerFields& fields() { return *manager; } // "the further convenience"
private:
Manager* manager;
};
class SpecificEvent: public Event {
public:
SpecificEvent(Manager* m, int p) : Event{m}, param{p} {}
void process() override { fields().dataInt = param; } // "friend inheritance" usage
private:
int param;
};
See the comments in the code.
The Situation
My company has a QML-based application which displays some content using a custom OpenGL-based render plugin (MyGame). This plugin has a few critical needs:
To be able to effect changes in the renderer in response to QML-based signals.
(e.g. change the position of an object rendered by the game)
To only process these changes at a specific spot in MyGame's redraw loop.
(This is very important; MyGame is very sensitive about when changes are allowed.)
To have the plugin redraw at 60Hz (at least).
The Problem
The code we have right now honors (1) and (2), but fails (3); the plugin does not get visually updated consistently. (The updates are erratic, at an estimated 5-10Hz.) I believe that the plugin we have created—based on QQuickFramebufferObject—is not taking proper advantage of how Qt/QML intended the scene graph to be updated.
How can I re-structure my plugin so that I get all three of the above?
The Code
Overview:
The plugin creates a QQuickFramebufferObject (MyPlugin) and a QQuickFramebufferObject::Renderer (MyRenderer).
When MyRenderer::render() is called it calls MyGame::Redraw() itself, and then calls update().
MyGame::Redraw() does what it needs to, and at the right spot where changes can be accepted, emits a timeToMakeChanges QML signal on MyPlugin.
QML listens for the onTimeToMakeChanges signal and invokes methods on the plugin that affect MyGame.
To workaround the problem of low-frequency visual updates, I've found that if I overlay a QML Canvas over my plugin and redraw the canvas frequently using a Timer, my plugin starts to get visually updated at what appears to be around 60Hz. Clearly this is a gross hack.
Following is a summary of the code setup. Please forgive missing/incorrect code; I'm trying to distill thousands of lines of glue code down to the essentials for this question.
MyPlugin.h
#include <QOpenGLFramebufferObject>
#include <QQuickFramebufferObject>
class MyPlugin : public QQuickFramebufferObject {
Q_OBJECT
public:
MyPlugin();
virtual ~MyPlugin();
virtual QQuickFramebufferObject::Renderer* createRenderer() const;
signals:
void timeToMakeChanges();
public slots:
void makeChanges(QVariant inValue);
void HandleWindowChanged(QQuickWindow *inWindow);
private:
MyGame* GetGame() { ... }
};
MyPlugin.cpp
#include "MyPlugin.h"
#include <MyGame.h>
// ******************************************************************
class MyRenderer:
public QObject,
public QQuickFramebufferObject::Renderer,
protected QOpenGLFunctions
{
Q_OBJECT
public:
virtual void render();
private:
static void RequestGameChanges();
};
void MyRenderer::render() {
if ( !m_Initialized ) {
QOpenGLFramebufferObject *theFbo = this->framebufferObject();
InitializeGl( theFbo ); // Not shown
m_MyGame = &MyGame::Create();
m_MyGame->RegisterCallback(
reinterpret_cast<qml_Function>(MyRenderer::RequestGameChanges)
);
m_Initialized = true;
}
m_MyGame->RestoreState();
m_MyGame->Redraw();
m_MyGame->SaveState();
m_PluginItem->window()->resetOpenGLState();
// Tell QML that we want to render again as soon as possible
update();
}
// This gets invoked in the middle of m_MyGame->Redraw()
void MyRenderer::RequestGameChanges() {
emit m_PluginItem->timeToMakeChanges();
}
// ******************************************************************
MyPlugin::MyPlugin() {
setMirrorVertically(true);
connect(
this, SIGNAL(windowChanged(QQuickWindow*)),
this, SLOT(HandleWindowChanged(QQuickWindow*))
);
}
void MyPlugin::HandleWindowChanged(QQuickWindow *inWindow) {
inWindow->setClearBeforeRendering(false);
}
void MyPlugin::makeChanges(QVariant inValue) {
MyGame *theGame = GetGame();
// Send the requested changes to theGame
}
QQuickFramebufferObject::Renderer* MyPlugin::createRenderer() const {
m_Renderer = new MyRenderer( *this );
}
MyApp.qml
import MyPlugin 1.0
Window {
MyPlugin {
property var queuedUpChanges: ([])
onSomeOtherSignal: queueUpChangesToMake();
onTimeToMakeChanges: makeChanges( queuedUpChanges );
}
Canvas { id:hack }
Timer {
interval:10; running:true; repeat:true
onTriggered: hack.changeWhatYouShow();
}
}
Bonus Points
The main question is "How do I modify my code so that I get 60Hz updates?" However, as seen in the QML, the setup above requires me to queue up all changes in QML so that they are able to be applied during the right spot in the MyGame::Render().
Ideally, I'd prefer to write QML without timeToMakeChanges, like:
MyPlugin {
onSomeOtherSignal: makeChanges( ... );
}
If there's a way to accomplish this (other than queuing up the changes in C++ instead)—perhaps something related to synchronize() I'd love to know about it.
I'd make a timer in QML that calls the makeChanges regularly. But store all the state in MyPlugin. Then, in Renderer::synchronize(), copy from MyPlugin to MyRenderer, so it can be used by the MyGame.
(although, I wouldn't do any gamelogic-related calculations in QML ever in the first place)
I'm writing a C++ programm using GTK+3.0. Anyway, I think this question may apply to any framework that uses events / signals.
I have a container class, say containerClass and a child class, say childClass. A childClass object child is contained inside a containerClass object container.
The child object is written to modify properties of something. To this aim, it has GtkEntry, GtkButton and so on. When I click the "save button", an event is raised.
This event must be handled by the container object, because the container is interfaced with a database in someway.
Hereafter, you find the solution I'm using to do the job:
// Child class
class childClass {
void setClickHandler_External(void (*extFun)(string property), void *);
void (*clickHandler_External)(string, void *);
void *clickHandler_External_Data;
static void buttonClicked(GtkWidget *widget, void *data);
}
void childClass::setClickHandler_External(void (*extFun)(string), void *data) {
// Set the external event handler
clickHandler_External = extFun;
clickHandler_External_Data = data;
}
void childClass::buttonClicked(GtkWidget *widget, void *data) {
childClass *m = (childClass *)data;
// Call the external event handler
m->clickHandler_External(property, m->clickHandler_External_Data);
}
// Container Class
class containerClass {
childClass child;
static void clickHandler(string property, void *data);
}
containerClass::containerClass() {
// Set the event handler
child.setClickHandler_External((void(*)(string))&(this->clickHandler), (void *)this);
}
void containerClass::clickHandler(string property, void *data) {
// Event handler in the upper class
containerClass *m = (containerClass *)data;
//FINALLY, DO THE JOB WITH PROPERTY!!!
}
This works well and does the job. Anyway, I was wondering if there is a smarter and cleaner way to achieve the same aim, maybe without using pointers to static functions, or by defining some kind of pattern to be reused everytime I need to have the same mechanism.
Thanks in advance
Gtkmm uses the sigc++ library to take care of all of this for you. There is no need to write it yourself.
Documentation links:
Signals overview
Appendix with detailed information
So, in this case, I would use something like
button.signal_clicked().connect(sigc::mem_fun(container, &containerClass::clickHandler));
while making sure that containerClass::clickHander has the appropriate number of arguments.
My first suggestion would be to use use templates to improve the type safety of what you are doing:
template< class ParamType >
void childClass::setClickHandler_External(void (*extFun)(string, ParamType *),
ParamType *data)
{
// Set the external event handler
clickHandler_External = (void ()(string,void*))extFun;
clickHandler_External_Data = (void*)data;
}
Then you can simplify the containerClass implementation as such:
// Container Class
class containerClass {
childClass child;
static void clickHandler(string property, containerClass *data);
}
containerClass::containerClass() {
// Set the event handler
child.setClickHandler_External(&containerClass::clickHandler, this);
}
void containerClass::clickHandler(string property, containerClass *data) {
//FINALLY, DO THE JOB WITH PROPERTY!!!
}
While it's great that this cleans up the implementation, removing the explicit casting from all the container implementors, that's not really the point. The point is to prevent you from passing wrong pointers into setClickHandler_External, causing crashes on the back end when events get dispatched.
My next step would take us further from your implementation, but would require more details about what you are actually doing. Depending on your needs that would be looking into:
Inheritance: should containerClass derive from childClass? That would provide access to a virtual function table that we could override.
Functors: look at boost::function and boost::bind to implement functors, eliminating the intermediate static function call.
Lambda Functions: bleeding edge (C++11 or later), but may be a good fit for this kind of forwarding function.
I am developing GUI form in Qt and I wonder how to implement ObserverPattern. Form can subscribe to many data streams distinguished by tickerId, when data stream arrives (new quote is available) my PosixClient (socket wrapper) fires notifyObservers() method what results in update() method of observer being executed.
BUT:
this update() method is void update() and I need to take incoming data records and plot them, count something, just use them. So how can I achieve this, how pass data records to observer?
Data is available to Observable (MarketData object derived from Observable). When data arrives I push it into this Observable and notify observers.
void PosixClient::tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute) {
printf("tradingclient_1: tickPrice: \n");
for(std::vector<boost::shared_ptr<MarketData> >::iterator it=dataRepository.begin();
it!=dataRepository.end(); it++){
if((*it)->tickerId==tickerId){
(*it)->tickPriceData.push_back(tickSizeRecord(field,price,canAutoExecute));
(*it)->notifyObservers();
//TODO: start thread to store incoming data in repository
}
}
}
Their void update() methods are then called. in order to retrieve a data from this function I decided to pass a function pointer boost::function<> to it as a callback and Observer calls this function pointer that points to my GUI object with incoming data from observable as argument. Is this right approach?
struct MarketData : public QuantLib::Observable {
//public:
MarketData();
MarketData(IB::Contract c, int tickerId):c(c),tickerId(tickerId){}
MarketData(const MarketData& orig);
virtual ~MarketData();
std::vector<IB::Record> tickPriceData; //market data fed in tickPrice
//private:
IB::Contract c;
int tickerId;
};
typedef boost::shared_ptr<MarketData> pMyObservable;
typedef boost::function<void (int tickerId, IB::Record record)> f_action_ptr;
class MarketDataObserver : public QuantLib::Observer{
public:
MarketDataObserver(pMyObservable obs, f_action_ptr ptr)
: observable(obs), f_ptr(ptr){
this->registerWith(observable);
}
MarketDataObserver(const MarketDataObserver &observer)
: Observer(observer),
observable(observer.observable){ // faction_ptr is not copied!
}
void update(){
data=observable->tickPriceData.back();
//printf("new data: %l\n",data.price);
f_ptr(observable->tickerId, data);
}
private:
IB::Record data;
pMyObservable observable;
f_action_ptr f_ptr;
};
PLEASE NOTE:
I am aware of Qt signal/slot mechanism, but in my opinion Qt signal/slot is not at all solution here, when I need dynamically subscribe to data, plot them, show on Qt Form, then delete subscription when Form is canceled. But maybe I am wrong. Am I? I ask for real, working examples, from life, not theoretical dispute.
The usual Qt idiom for the observer pattern are indeed signals and slots. Have the source of the data emit signals and pass the data as an argument of the signal. That's how this is done within Qt -- signals are not used just for the GUI events.
I have a toolbar controller which is capable of updating the toolbar state ( enabled/disabled, pressed/unpressed ) by querying document properties or the application framework. I have some buttons that represent the current state of a view.
From an application design standpoint I like having toolbar controller able to update the button state at any time given a document. I also prefer the toolbar controller & button handlers to have no internal state.
Options as I see it - looking for other suggestions:
Create a mechanism for visiting all views of a document with a visitor that can capture the state of the view which is then used to enable/disable/press/depress the button.
Create some connection between views and toolbar handlers that allows the toolbar buttons to directly ask the views.
Other??
you can try having an event loop for the view and update the state with a function call dispatch
Like this:
class ViewEventArgs{
public:
int eventNumber;
};
class ViewEvent{
public:
virtual void onViewChange(ViewEventChangeArgs args) = 0;
};
class ViewController{
public:
virtual void doPressed() = 0;
virtual void doChecked() = 0;
//other interface methods
};
class ToolbarView : public ViewEvent{
public:
//Your EVENT-LOOP kernel will fire these events depending upon the state change in the view
void onViewChange(ViewEventChangeArgs args)
{
switch(args.eventNumber){
case PRESSED:
getToolbarController()->doPressed();//the method dispatch
break;
case CHECKED:
getToolbarController()->doChecked();
}
}
//other parts of the view
};
class ToolbarController: public ViewController{
public:
void doPressed() { /*pressed*/ }
void doChecked() { /*checked*/ }
//implementations
};