This is a plugin system which is based on the factory pattern.
Each plugin extends the Plugin class and implements a factory that returns the extended class to the kernel.
Plugins are compiled as shared libraries. Kernel checks the plugins/ directory and loads all libraries at runtime.
When the red button is clicked, the kernel calls call_on_red_click() on every loaded plugin.
// Plugin.h
class Plugin {
public:
virtual void call_on_blue_click() = 0;
virtual void call_on_red_click() = 0;
}
// MyPlugin.h
class MyPlugin : public Plugin {
public:
void call_on_blue_click() {/*[...]*/}
void call_on_red_click() {
// Does something
// Optionaly, activate teleporter
}
}
Plugin *plug_factory() { return new MyPlugin; }
// MyOtherPlugin.h
class MyOtherPlugin : public Plugin {
public:
void call_on_blue_click() {/*[...]*/}
void call_on_red_click() {
// Does something else
// Optionaly, activate teleporter
}
}
Plugin *plug_factory() { return new MyOtherPlugin; }
The teleporter is compiled separately and may not be present in every installation (It's shiped by itself).
Lets say that MyPlugin and MyOtherPlugin want to activate the teleporter if it is present.
Questions:
Should the Teleporter be a kernel Plugin or something else?
Is there a design pattern for this?
Sounds like you want the decorator pattern
Which will allow you to have a class that loads the dll, and then your plugins can then query your decorator if teleportation is enabled. You can then disable it for any reason, not just because the dll isn't there; or enable it even if the dll isn't there but implemented in another way.
Related
i have application that load plugins dynamically. each plugin has it's own pluginname.qml file. i need to access the plugins methods from pluginname.qml files.
obviously i can't use QQmlContext::setContextPropert("" ,*object) because of abstract interface of plugins. so what is the proper way to create functionality like this. how can i access the methods of plugin directly from qml(expose plugin methods to qml)? sry for bad english :)
playerView.qml:
Component.onCompleted:
{
ViewManager.requestPlugin("playerPlugind.dll"); // ViewManager signal connected to PluginLoader void onPluginRequest() slot
}
PluginLoader.cpp:
bool PluginLoader::loadPlugin(QString plugin_name)
{
QDir pluginDirectory = QCoreApplication::applicationDirPath();
pluginDirectory.cd("Plugins");
QPluginLoader pluginLoader(pluginDirectory.filePath(plugin_name));
QObject* instance = pluginLoader.instance();
if(instance)
{
m_player_interface = qobject_cast<PlayerInterface *>(instance);
if(m_player_interface )
return true;
}
return 0;
}
void PluginLoader::onPluginRequest(QString plugin_name)
{
loadPlugin(plugin_name);
}
this answer is kind of silly ,but we can make a member function in interface class like this :
virtual void contextRegister(QQmlContext* rootContext) = 0;
then in the plugin we implement the member function:
void FirstPlugin::registerContext(QQmlContext* rootContext)
{
rootContext->setContextProperty("PlayerInterface" , this);
}
at the end ,when plugin loaded completely we can call this function :
playerInterface->contextRegister(m_rootContext);
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 have several modules in my program (e.g. Database, Scheduler) which uses same entity - some game server.
Main goal is that each module uses game server API with limited functionality (functionality which need for interaction between separate module and game server only) and other functions must be hide.
I have created such functionality. But I don't now, maybe it's wrong realization or maybe somebody guess better method.
Class which placed below contain some operations which can be access only from others modules via classes wrappers.
#ifndef _GAMESERVER_
#define _GAMESERVER_
#include <vector>
class GameServer
{
static GameServer instance;
std::vector<int> game_actions;
GameServer(){}
~GameServer(){}
GameServer(const GameServer&){}
protected:
void addGameAction(int action) // Some functionality, which can be accessible only from others modules via classes wrapers
{
game_actions.push_back(action);
}
public:
static GameServer *getInstance()
{
return &instance;
}
bool start()
{
return true;
}
void stop()
{
}
};
#endif
Below placed class 'wrapper' for class GameServer which has been realising API for interaction with module Database.
#ifndef _DBGAMESERVER_
#define _DBGAMESERVER_
/* Database module will use this API for interacting with game server */
class GameServer;
class DBGameServer : protected GameServer
{
DBGameServer();
public:
static DBGameServer *getInstance()
{
return static_cast<DBGameServer *>(GameServer::getInstance());
}
void addGameAction(int action)
{
GameServer::addGameAction(action);
}
};
#endif
Thanks!
You are creating your singleton instance at first call to getIntance. It may be unsafe in a multithreaded application : race conditions could lead to multiple instances being actually intialized and used.
IMHO you would better use static initialization :
Declaration :
...
class GameServer {
static GameServer& instance;
// private constructor, copie constructor and destructor
...
public:
static GameServer * getInstance() { return &instance; }
...
}
Implementation :
...
GameServer & GameServer::instance = GameServer();
...
That way you are sure that the object is constructed only once during program start (before first instruction), and destructor is called at program end (after last instruction). Of course if constructor throws an exception the program will stop abruptly before it is given any chance to display anything : the eventual error messages should be displayed inside constructor.
I have a user control that has button whose click event handler contains the core logic. I want to test this button click handler.
This handler function calls a public function of another user control (which resides in separate C# project) which ultimately calls public function of a reference assembly.
Can anyone please tell me - how will be the unit test for such a handler?
In unit testing, we test the Unit - in this case, the user control. And nothing more. But we shouldn't allow the user control to access outside world, we should use mocking techniques.
In example, if your UserControlA calls UserControlB, create an interface for UserControlB and replace it with a mock UserControlB :
class UserControlA {
UserControlBInterface BReference;
public void setBReference(UserControlBInterface reference) { this.BReference = reference };
void OnClick (...) { BReference.callAMethod(); }
}
class MockupForB : UserControlBInterface {
boolean called=false;
public void callAMethod() { this.called = true; }
}
class TesterA : UnitTest {
public void testOnClick()
{ UserControlA a = new UserControlA(); MockupForB mockup = new MockupForB(); a.setBReference(mockup);
a.Button1.PerformClick(...); //following Aaronontheweb's advice
assertTrue(mockup.called,"the method callAMethod not being called by UserControlA");
}
}
And to ensure UserControlB indeed calls a reference library, this belongs to unit test for UserControlB.
You can write a method that programmatically raises the Click event and call that from your unit test.
Edit: Ah, this actually exists already: http://msdn.microsoft.com/en-us/library/hkkb40tf(VS.90).aspx
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);
}
}
}