This patch modifies the skeleton plugin and some core stuff to make the screen scrollable via middle mouse drag, but it's just to test the propagation of SDL::Event to the plugins.
It works but I don't know if it is the proper way to propagate the events.
I would really appreciate it if you reviewed that propagation code as I still learning C/CPP and there might be some problems.
From d078a8a3b6d623f9701166121e4710d9582160ee Mon Sep 17 00:00:00 2001
From: Lothiack <Lothiackgmailcom>
Date: Thu, 15 Dec 2011 00:55:11 -0200
Subject: [PATCH] Propagate SDL::Event to plugins.
---
library/Core.cpp | 63 +++++++++++++++++++++++++++++-
library/PluginManager.cpp | 27 ++++++++++++-
library/include/dfhack/PluginManager.h | 3 +
plugins/server/main.cpp | 4 +-
plugins/skeleton/skeleton.cpp | 67 +++++++++++++++++++++++++++++++-
5 files changed, 158 insertions(+), 6 deletions(-)
diff --git a/library/Core.cpp b/library/Core.cpp
index f218f27..9ccd2d4 100644
--- a/library/Core.cpp
+++ b/library/Core.cpp
@@ -353,7 +353,7 @@ void fIOthread(void * iodata)
{
con.clear();
}
- else if(first == "die")
+ else if(first == "die" || first == "exit" || first == "quit")
{
_exit(666);
}
@@ -681,12 +681,73 @@ bool Core::ncurses_wgetch(int in, int & out)
return true;
}
+//int32_t screenX = 0;
+//int32_t screenY = 0;
+//int32_t screenZ = 0;
+//int32_t mouseX = 0;
+//int32_t mouseY = 0;
+//bool ignoreEvent;
+//
+//uint8_t lastEventType = 0;
+
int Core::SDL_Event(SDL::Event* ev, int orig_return)
{
// do NOT process events before we are ready.
if(!started) return orig_return;
if(!ev)
return orig_return;
+
+
+ /*ignoreEvent = lastEventType == ev->type;
+ lastEventType = ev->type;*/
+ SDL::Event evClone = *ev;
+
+ plug_mgr->OnEvent(evClone);
+
+ //if((ev->type == SDL::ET_MOUSEBUTTONDOWN || ev->type == SDL::ET_MOUSEBUTTONUP) && ev->button.button == 2 && !ignoreEvent)
+ //{
+ //
+
+ // SDL::MouseButtonEvent * me = (SDL::MouseButtonEvent *)ev;
+ //
+
+
+ // int32_t mx;
+ // int32_t my;
+ // int32_t mapW;
+ // int32_t mapH;
+
+ // getGui()->getMousePos(mx,my);
+ //
+ // //->getSize(mapW, mapH, mapH);
+
+ // switch(ev->type)
+ // {
+ // case SDL::ET_MOUSEBUTTONDOWN:
+ // con.print("Mouse Down - X:%d Y:%d\n", mx, my);
+ // mouseX = mx;
+ // mouseY = my;
+ // break;
+ //
+ // case SDL::ET_MOUSEBUTTONUP:
+ // con.print("Mouse Up - X:%d Y:%d\n",mx, my);
+ // mouseX -= mx;
+ // mouseY -= my;
+ // getGui()->getViewCoords(screenX,screenY,screenZ);
+ // con.print("Drag - X:%d Y:%d\n", mouseX, mouseY);
+ // screenX += mouseX;
+ // screenY += mouseY;
+ // screenX = screenX < 0 ? 0 : screenX;
+ // screenY = screenY < 0 ? 0 : screenY;
+ // getGui()->setViewCoords(screenX,screenY,screenZ);
+ // break;
+
+ // /*case SDL::ET_MOUSEMOTION:
+ // con.print("Mouse Move\n");
+ // break;*/
+ // }
+ //}
+
if(ev && ev->type == SDL::ET_KEYDOWN || ev->type == SDL::ET_KEYUP)
{
SDL::KeyboardEvent * ke = (SDL::KeyboardEvent *)ev;
diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp
index 7a7bb09..076da6c 100644
--- a/library/PluginManager.cpp
+++ b/library/PluginManager.cpp
@@ -45,7 +45,7 @@ using namespace tthread;
#endif
#include <assert.h>
-
+#include "dfhack/SDL_fakes/events.h"
static int getdir (string dir, vector<string> &files)
{
DIR *dp;
@@ -135,6 +135,7 @@ Plugin::Plugin(Core * core, const std::string & filepath, const std::string & _f
plugin_shutdown = 0;
plugin_status = 0;
plugin_onupdate = 0;
+ plugin_onevent = 0;
state = PS_UNLOADED;
access = new RefLock();
}
@@ -191,6 +192,7 @@ bool Plugin::load()
}
plugin_status = (command_result (*)(Core *, std::string &)) LookupPlugin(plug, "plugin_status");
plugin_onupdate = (command_result (*)(Core *)) LookupPlugin(plug, "plugin_onupdate");
+ plugin_onevent = (command_result (*)(Core *, SDL::Event ev)) LookupPlugin(plug, "plugin_onevent");
plugin_shutdown = (command_result (*)(Core *)) LookupPlugin(plug, "plugin_shutdown");
//name = _PlugName();
plugin_lib = plug;
@@ -299,6 +301,20 @@ command_result Plugin::on_update()
return cr;
}
+command_result Plugin::on_event(SDL::Event ev)
+{
+ Core & c = Core::getInstance();
+
+ command_result cr = CR_NOT_IMPLEMENTED;
+ access->lock_add();
+ if(state == PS_LOADED && plugin_onevent)
+ {
+ cr = plugin_onevent(&c, ev);
+ }
+ access->lock_sub();
+ return cr;
+}
+
Plugin::plugin_state Plugin::getState() const
{
return state;
@@ -370,6 +386,15 @@ void PluginManager::OnUpdate( void )
all_plugins[i]->on_update();
}
}
+
+void PluginManager::OnEvent( SDL::Event ev )
+{
+ for(int i = 0; i < all_plugins.size(); i++)
+ {
+ all_plugins[i]->on_event(ev);
+ }
+}
+
// FIXME: doesn't check name collisions!
void PluginManager::registerCommands( Plugin * p )
{
diff --git a/library/include/dfhack/PluginManager.h b/library/include/dfhack/PluginManager.h
index fef1aea..0fec8c7 100644
--- a/library/include/dfhack/PluginManager.h
+++ b/library/include/dfhack/PluginManager.h
@@ -87,6 +87,7 @@ namespace DFHack
Plugin(DFHack::Core* core, const std::string& filepath, const std::string& filename, PluginManager * pm);
~Plugin();
command_result on_update();
+ command_result on_event(SDL::Event ev);
public:
bool load();
bool unload();
@@ -117,6 +118,7 @@ namespace DFHack
command_result (*plugin_status)(Core *, std::string &);
command_result (*plugin_shutdown)(Core *);
command_result (*plugin_onupdate)(Core *);
+ command_result (*plugin_onevent)(Core *, SDL::Event ev);
};
class DFHACK_EXPORT PluginManager
{
@@ -126,6 +128,7 @@ namespace DFHack
PluginManager(Core * core);
~PluginManager();
void OnUpdate( void );
+ void OnEvent( SDL::Event ev );
void registerCommands( Plugin * p );
void unregisterCommands( Plugin * p );
// PUBLIC METHODS
diff --git a/plugins/server/main.cpp b/plugins/server/main.cpp
index b47128c..8aa5f7b 100644
--- a/plugins/server/main.cpp
+++ b/plugins/server/main.cpp
@@ -23,9 +23,9 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
{
// Fill the command list with your commands.
commands.clear();
- commands.push_back(PluginCommand("server",
+ /*commands.push_back(PluginCommand("server",
"Inane zeromq example turned into a plugin.",
- server));
+ server));*/
return CR_OK;
}
diff --git a/plugins/skeleton/skeleton.cpp b/plugins/skeleton/skeleton.cpp
index d69a2dd..bc1e513 100644
--- a/plugins/skeleton/skeleton.cpp
+++ b/plugins/skeleton/skeleton.cpp
@@ -5,11 +5,13 @@
#include <dfhack/Console.h>
#include <dfhack/Export.h>
#include <dfhack/PluginManager.h>
+
using namespace DFHack;
// our own, empty header.
#include "skeleton.h"
-
+#include <dfhack/modules/Gui.h>
+#include "dfhack/SDL_fakes/events.h"
// Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom
@@ -30,7 +32,68 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
"Do nothing, look pretty.",
skeleton /*,
true or false - true means that the command can't be used from non-interactive user interface'*/));
- return CR_OK;
+ return CR_OK;
+}
+
+int32_t screenX = 0;
+int32_t screenY = 0;
+int32_t screenZ = 0;
+int32_t mouseX = 0;
+int32_t mouseY = 0;
+bool ignoreEvent;
+
+uint8_t lastEventType = 0;
+
+DFhackCExport command_result plugin_onevent ( Core * c, SDL::Event ev )
+{
+ ignoreEvent = lastEventType == ev.type;
+ lastEventType = ev.type;
+
+ if((ev.type == SDL::ET_MOUSEBUTTONDOWN || ev.type == SDL::ET_MOUSEBUTTONUP) && ev.button.button == 2 && !ignoreEvent)
+ {
+
+
+ SDL::MouseButtonEvent * me = (SDL::MouseButtonEvent *)&ev;
+
+
+
+ int32_t mx;
+ int32_t my;
+ int32_t mapW;
+ int32_t mapH;
+
+ c->getGui()->getMousePos(mx,my);
+
+ //->getSize(mapW, mapH, mapH);
+
+ switch(ev.type)
+ {
+ case SDL::ET_MOUSEBUTTONDOWN:
+ c->con.print("Mouse Down - X:%d Y:%d\n", mx, my);
+ mouseX = mx;
+ mouseY = my;
+ break;
+
+ case SDL::ET_MOUSEBUTTONUP:
+ c->con.print("Mouse Up - X:%d Y:%d\n",mx, my);
+ mouseX -= mx;
+ mouseY -= my;
+ c->getGui()->getViewCoords(screenX,screenY,screenZ);
+ c->con.print("Drag - X:%d Y:%d\n", mouseX, mouseY);
+ screenX += mouseX;
+ screenY += mouseY;
+ screenX = screenX < 0 ? 0 : screenX;
+ screenY = screenY < 0 ? 0 : screenY;
+ c->getGui()->setViewCoords(screenX,screenY,screenZ);
+ break;
+
+ /*case SDL::ET_MOUSEMOTION:
+ con.print("Mouse Move\n");
+ break;*/
+ }
+ }
+
+ return CR_OK;
}
// This is called right before the plugin library is removed from memory.
--
1.7.8.msysgit.0