summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2019-01-22 14:01:30 +0100
committerNao Pross <naopross@thearcway.org>2019-01-22 14:01:30 +0100
commit59e71b7dbd321eb3dc2ed7afecb66840115c3c15 (patch)
treecc8dce2f732b90b12bbc5b46c50fd434df4aba14
parentAdd test for task and job, fix bug in job (diff)
parentDuplicate (diff)
downloadflatland-59e71b7dbd321eb3dc2ed7afecb66840115c3c15.tar.gz
flatland-59e71b7dbd321eb3dc2ed7afecb66840115c3c15.zip
Merge remote-tracking branch 'raffa/master'
-rw-r--r--engine/flatcomponent.cpp4
-rw-r--r--engine/flatland.cpp16
-rw-r--r--engine/flatobject.cpp61
-rw-r--r--engine/flatserial.cpp2
-rw-r--r--engine/flatsignal.cpp176
-rw-r--r--engine/flatsurface.cpp10
-rw-r--r--engine/flatwindow.cpp14
-rw-r--r--engine/include/flatbound.h4
-rw-r--r--engine/include/flatcollector.h4
-rw-r--r--engine/include/flatcomponent.h4
-rw-r--r--engine/include/flatobject.h36
-rw-r--r--engine/include/flatserial.h4
-rw-r--r--engine/include/flatsignal.h100
-rw-r--r--engine/include/flatsurface.h8
-rw-r--r--engine/include/flatwindow.h6
-rw-r--r--engine/include/object.hpp42
-rw-r--r--engine/include/serial/focusable.h8
-rw-r--r--engine/include/serial/keyfocusable.h2
-rw-r--r--engine/include/signal.hpp112
-rw-r--r--engine/include/types.hpp (renamed from engine/include/types.h)13
-rw-r--r--engine/keyfocusable.cpp2
-rw-r--r--engine/object.cpp62
-rw-r--r--engine/signal.cpp191
-rw-r--r--test/test3.cpp120
24 files changed, 581 insertions, 420 deletions
diff --git a/engine/flatcomponent.cpp b/engine/flatcomponent.cpp
index 33cfbbc..06b558c 100644
--- a/engine/flatcomponent.cpp
+++ b/engine/flatcomponent.cpp
@@ -1,5 +1,5 @@
#include "flatcomponent.h"
-#include "flatsignal.h"
+#include "signal.h"
Component::Component(Component *parent, const std::string& id)
: parent(parent)
@@ -7,7 +7,7 @@ Component::Component(Component *parent, const std::string& id)
// TODO, check flatland initialization
if (id.empty())
- setID(FlatObject::randomID());
+ setID(flat::core::object::randomID());
if (parent == 0)
{
diff --git a/engine/flatland.cpp b/engine/flatland.cpp
index 2f1c920..628331b 100644
--- a/engine/flatland.cpp
+++ b/engine/flatland.cpp
@@ -10,14 +10,14 @@
using namespace std;
#include "flattask.h"
-#include "flatsignal.h"
+#include "signal.h"
#include "flatwindow.h"
#include "flatexception.h"
#include "exceptions/forcequit.h"
float flatland_dt;
-set<FlatObject*> objects;
+set<flat::core::object*> objects;
FlatWindow * window = 0;
SignalChannel * core = 0;
@@ -29,9 +29,9 @@ flat_status status;
float fps;
float fps_pause = 5;
-Uint32 status_to_flags(const flat_status& s)
+uint32_t status_to_flags(const flat_status& s)
{
- Uint32 flags = 0;
+ uint32_t flags = 0;
if (s.audio)
flags |= SDL_INIT_AUDIO;
@@ -60,7 +60,7 @@ Uint32 status_to_flags(const flat_status& s)
/* Listen to simple quit calls */
class QuitListener : public FlatListener
{
- virtual void callback(FlatObject*, void*) override
+ virtual void callback(flat::core::object*, void*) override
{
/* Order to quit */
quit_flatland();
@@ -97,7 +97,7 @@ int init_flatland(FlatWindow* w, gameloop loop, const flat_status& s, float _fps
cout << "Flatland: Initializing SDL" << endl;
- Uint32 flags = status_to_flags(s);
+ uint32_t flags = status_to_flags(s);
if ( SDL_Init(flags | SDL_INIT_NOPARACHUTE) < 0)
{
@@ -170,13 +170,13 @@ int init_flatland(FlatWindow* w, gameloop loop, const flat_status& s, float _fps
quit_flatland();
}
- SDL_Delay((Uint32) (1000.0f / fps));
+ SDL_Delay((uint32_t) (1000.0f / fps));
delay -= clock();
} while (status.loop);
- SDL_Delay((Uint32)(1000 / fps_pause));
+ SDL_Delay((uint32_t)(1000 / fps_pause));
}
while(status.running);
diff --git a/engine/flatobject.cpp b/engine/flatobject.cpp
deleted file mode 100644
index a325942..0000000
--- a/engine/flatobject.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "flatobject.h"
-
-#include <stdlib.h>
-
-using namespace std;
-
-list<FlatObject*> FlatObject::allObjects;
-
-FlatObject::FlatObject()
-{
- /* Collect this object */
- FlatObject::allObjects.push_back(this);
-}
-
-FlatObject::~FlatObject()
-{
- /* Eliminate this object reference */
- FlatObject::allObjects.remove(this);
-}
-
-void FlatObject::setID(const string& id)
-{
- this->id = id;
-}
-
-const string& FlatObject::getID() const
-{
- return id;
-}
-
-string FlatObject::randomID(Uint8 length) {
-
- string out;
-
- for (Uint8 i = 0; i < length; ++i)
- out += (char)(rand() % 93 + 33);
-
- return out;
-}
-
-bool FlatObject::isAllocated(FlatObject *obj)
-{
- for (FlatObject * o : FlatObject::allObjects)
- {
- if (o == obj)
- return true;
- }
-
- return false;
-}
-
-vector<FlatObject*>& FlatObject::getByID(const string& id, vector<FlatObject*>& l)
-{
- for (FlatObject * obj : FlatObject::allObjects)
- {
- if (id == obj->getID())
- l.push_back(obj);
- }
-
- return l;
-}
diff --git a/engine/flatserial.cpp b/engine/flatserial.cpp
index 9c49787..7259bf1 100644
--- a/engine/flatserial.cpp
+++ b/engine/flatserial.cpp
@@ -62,7 +62,7 @@ void SDL_EventCollector::erase(void*)
user.clear();
}
-const std::vector<SDL_Event>& SDL_EventCollector::getStack(Uint32 id) const
+const std::vector<SDL_Event>& SDL_EventCollector::getStack(uint32_t id) const
{
switch(id)
{
diff --git a/engine/flatsignal.cpp b/engine/flatsignal.cpp
deleted file mode 100644
index a739efc..0000000
--- a/engine/flatsignal.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-#include "flatsignal.h"
-#include "flattask.h"
-
-using namespace std;
-
-bool sig_prior_cmp::operator()(const FlatSignal& s, const FlatSignal& g) const
-{
- return s.priority <= g.priority;
-}
-
-map<string, SignalChannel*> SignalChannel::channels;
-
-SignalChannel::SignalChannel(const string& id, bool pre_process)
-{
- SignalChannel * other = findChannel(id);
-
- if (!other)
- //TODO throw exception
- ;
-
- /* Initialize task, post-process, fifth priority */
- checker = new FlatTask<SignalChannel>( this,
- &SignalChannel::post_processing,
- 0,
- pre_process,
- pre_process ? 2 : 10);
-
- string ID = (id.empty()) ? FlatObject::randomID() : id;
-
- setID(ID);
-
- channels.insert(pair<string, SignalChannel*>(ID, this));
-}
-
-SignalChannel::~SignalChannel()
-{
- channels.erase(getID());
-
- /* Finalize task */
- delete checker;
-}
-
-void SignalChannel::emit(const FlatSignal& sig)
-{
- if (!sig.priority) {
-
- /* Execute immediately */
- for (auto listener : listeners)
- listener->execute(sig);
-
- } else
- /* Insert in order of priority */
- stack.insert(sig);
-}
-
-void SignalChannel::connect(FlatListener* l)
-{
- /* Control not to double */
- for (auto listener : listeners)
- {
- if (listener == l)
- return;
- }
-
- listeners.push_back(l);
-}
-
-void SignalChannel::disconnect(FlatListener* l)
-{
- listeners.remove(l);
-}
-
-
-SignalChannel * SignalChannel::findChannel(const string& id)
-{
- if (id.empty())
- return 0;
-
- auto it = channels.find(id);
-
- return (it == channels.end()) ? 0 : (*it).second;
-}
-
-void SignalChannel::post_processing(void*)
-{
- if (!stack.empty()) {
-
- /* for each listener, catch signal */
- for (const auto& signal : stack)
- {
- for (auto listener : listeners)
- listener->execute(signal);
- }
-
- stack.clear();
- }
-}
-
-
-
-/* FlatSignal class */
-
-FlatSignal::FlatSignal(FlatObject *sender, const string& id, void *data, Uint8 priority)
- : sender(sender), data(data), priority(priority)
-{
- setID(id);
-}
-
-bool FlatSignal::emit(const string& channel) const
-{
- SignalChannel * chan = SignalChannel::findChannel(channel);
-
- if (!chan)
- return false;
-
- /* Finally emit in channel */
- chan->emit(*this);
-
- return true;
-}
-
-
-
-/* FlatListener class */
-
-FlatListener::FlatListener(const initializer_list<string>& filters)
- : filters(filters) {}
-
-bool FlatListener::checkInFilters(const std::string& filter) const
-{
- for (const auto& f : filters)
- {
- if (filter == f)
- return true;
- }
-
- return false;
-}
-
-void FlatListener::execute(const FlatSignal& sig)
-{
- if ((!sig.getID().empty() && checkInFilters(sig.getID())) ||
- (sig.getID().empty() && filters.empty()))
- callback(sig.sender, sig.data);
-}
-
-void FlatListener::addFilter(const std::string& f)
-{
- filters.push_back(f);
-}
-
-void FlatListener::removeFilter(const std::string& f)
-{
- filters.remove(f);
-}
-
-bool FlatListener::connect(const std::string& chan)
-{
- SignalChannel * c = SignalChannel::findChannel(chan);
-
- if (!c)
- c->connect(this);
-
- return c != 0;
-}
-
-bool FlatListener::disconnect(const std::string& chan)
-{
- SignalChannel * c = SignalChannel::findChannel(chan);
-
- if (!c)
- c->connect(this);
-
- return c != 0;
-}
-
diff --git a/engine/flatsurface.cpp b/engine/flatsurface.cpp
index 1970b71..b3291d6 100644
--- a/engine/flatsurface.cpp
+++ b/engine/flatsurface.cpp
@@ -4,9 +4,9 @@
using namespace std;
-FlatSurface::FlatSurface(const char *filename, Uint32 format, SDL_Surface *parent)
+FlatSurface::FlatSurface(const char *filename, uint32_t format, SDL_Surface *parent)
- : FlatObject(), parent(parent), hide(false)
+ : flat::core::object(), parent(parent), hide(false)
{
setID(filename);
@@ -35,7 +35,7 @@ FlatSurface::FlatSurface(const char *filename, Uint32 format, SDL_Surface *paren
FlatSurface::FlatSurface(SDL_Surface *surface, SDL_Surface *parent)
- : FlatObject(), parent(parent), hide(false)
+ : flat::core::object(), parent(parent), hide(false)
{
this->surface = new SDL_Surface(*surface);
@@ -56,7 +56,7 @@ FlatSurface::FlatSurface(SDL_Surface *surface, SDL_Surface *parent)
FlatSurface::FlatSurface(const FlatSurface &sprite)
- : FlatObject(sprite), parent(sprite.parent),
+ : flat::core::object(sprite), parent(sprite.parent),
hide(sprite.hide)
{
offset = new SDL_Rect(*sprite.offset);
@@ -146,7 +146,7 @@ void FlatSurface::blit()
SDL_BlitSurface(surface, viewport, parent, offset);
}
-SDL_Surface * FlatSurface::loadOptimizedSurface(const char *filename, Uint32 format)
+SDL_Surface * FlatSurface::loadOptimizedSurface(const char *filename, uint32_t format)
{
SDL_Surface * optimized = 0;
diff --git a/engine/flatwindow.cpp b/engine/flatwindow.cpp
index ff17274..40cf1e3 100644
--- a/engine/flatwindow.cpp
+++ b/engine/flatwindow.cpp
@@ -3,7 +3,7 @@
#include <SDL2/SDL.h>
#include <iostream>
#include "flatlayer.h"
-#include "flatsignal.h"
+#include "signal.hpp"
using namespace std;
@@ -15,7 +15,7 @@ FlatWindow::FlatWindow( int x, int y,
: title(title), status(status),
sdl_window(0), screen(0)
{
- setID(title.c_str());
+ set_id(title);
bounds = new SDL_Rect;
@@ -47,7 +47,7 @@ FlatWindow::FlatWindow( int width, int height,
FlatWindow::FlatWindow(const FlatWindow& win)
- : FlatObject(win),
+ : flat::core::object(win),
title(win.title), status(win.status),
sdl_window(0), screen(0)
{
@@ -68,7 +68,7 @@ FlatWindow::~FlatWindow()
int FlatWindow::open()
{
- Uint32 win_flags = winstatus_to_flags(status);
+ uint32_t win_flags = winstatus_to_flags(status);
sdl_window = SDL_CreateWindow( title.c_str(),
bounds->x,
@@ -166,14 +166,14 @@ void FlatWindow::key_cb(const SDL_KeyboardEvent *event)
close();
/* Say flatland to quit */
- FlatSignal quit(this, "quit", 0, 0xff);
+ flat::core::signal quit(this, "quit", 0, 0xff);
quit.emit("core");
}
}
-Uint32 FlatWindow::winstatus_to_flags(window_status s)
+uint32_t FlatWindow::winstatus_to_flags(window_status s)
{
- Uint32 flags = 0;
+ uint32_t flags = 0;
if (s.fullscreen)
flags |= SDL_WINDOW_FULLSCREEN;
diff --git a/engine/include/flatbound.h b/engine/include/flatbound.h
index a80cd6e..f5a2c0d 100644
--- a/engine/include/flatbound.h
+++ b/engine/include/flatbound.h
@@ -1,12 +1,12 @@
#ifndef __FLATBOUND_H__
#define __FLATBOUND_H__
-#include "flatobject.h"
+#include "object.hpp"
#include "svector.h"
typedef SVector<int, 2> pixel;
-class FlatBound : virtual public FlatObject
+class FlatBound : virtual public flat::core::object
{
pixel location;
diff --git a/engine/include/flatcollector.h b/engine/include/flatcollector.h
index ed9a824..d7edf55 100644
--- a/engine/include/flatcollector.h
+++ b/engine/include/flatcollector.h
@@ -1,10 +1,10 @@
#ifndef __FLATCOLLECTOR_H__
#define __FLATCOLLECTOR_H__
-#include "flatobject.h"
+#include "object.hpp"
#include <set>
-class FlatCollector : virtual public FlatObject
+class FlatCollector : virtual public flat::core::object
{
FlatCollector * parent;
diff --git a/engine/include/flatcomponent.h b/engine/include/flatcomponent.h
index 8a14d90..807bcaa 100644
--- a/engine/include/flatcomponent.h
+++ b/engine/include/flatcomponent.h
@@ -1,10 +1,10 @@
#ifndef __FLAT_COMPONENT_H__
#define __FLAT_COMPONENT_H__
-#include "flatobject.h"
+#include "object.hpp"
#include <string>
-class Component : virtual public FlatObject
+class Component : virtual public flat::core::object
{
Component * parent;
diff --git a/engine/include/flatobject.h b/engine/include/flatobject.h
deleted file mode 100644
index 7ad1ddd..0000000
--- a/engine/include/flatobject.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __FLATOBJECT_H__
-#define __FLATOBJECT_H__
-
-#include <list>
-#include <vector>
-#include <string>
-#include <initializer_list>
-
-#include "types.h"
-
-class FlatObject
-{
- std::string id;
-
- /* Common list of objects */
- static std::list<FlatObject*> allObjects;
-
-public:
-
- FlatObject();
- ~FlatObject();
-
- void setID(const std::string&);
-
- const std::string& getID() const;
-
- /* Static accessors to allObject */
-
- static bool isAllocated(FlatObject*);
-
- static std::vector<FlatObject*>& getByID(const std::string& id, std::vector<FlatObject*>&);
-
- static std::string randomID(Uint8 length = 8);
-};
-
-#endif
diff --git a/engine/include/flatserial.h b/engine/include/flatserial.h
index f034690..b9e003f 100644
--- a/engine/include/flatserial.h
+++ b/engine/include/flatserial.h
@@ -1,7 +1,7 @@
#ifndef __FLATSERIAL_H__
#define __FLATSERIAL_H__
-#include "types.h"
+#include "types.hpp"
#include <vector>
#include "SDL2/SDL.h"
@@ -33,7 +33,7 @@ struct SDL_EventCollector
void collect(void*);
void erase(void*);
- const std::vector<SDL_Event>& getStack(Uint32 id) const;
+ const std::vector<SDL_Event>& getStack(uint32_t id) const;
};
namespace FlatSerial {
diff --git a/engine/include/flatsignal.h b/engine/include/flatsignal.h
deleted file mode 100644
index b20d082..0000000
--- a/engine/include/flatsignal.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __FLAT_SIGNAL_H__
-#define __FLAT_SIGNAL_H__
-
-#include <map>
-#include <list>
-#include <set>
-#include <initializer_list>
-#include "flatobject.h"
-#include "types.h"
-
-/* Post-process signal delivery when it's emitted */
-#define FSIG_PRIOR_INSTANT 0
-
-/* Process and emitted signal instantaneously */
-#define FSIG_PRIOR_DEFAULT 5
-
-class FlatSignal : virtual public FlatObject
-{
-
-public:
-
- FlatObject * sender;
- void * data;
- Uint8 priority;
-
- FlatSignal( FlatObject * sender,
- const std::string& id = "",
- void *data = 0,
- Uint8 priority = 5);
-
- /* Alias to SignalChannel::emit() */
- bool emit(const std::string& channel) const;
-};
-
-class FlatListener;
-
-/* Functor for order comparison */
-struct sig_prior_cmp {
-
- bool operator()(const FlatSignal&, const FlatSignal&) const;
-};
-
-typedef std::set<FlatSignal, sig_prior_cmp> SignalStack;
-
-/* Channel class */
-class SignalChannel : virtual public FlatObject
-{
- /* Post processing signal stacking */
- SignalStack stack;
-
- /* Listeners list */
- std::list<FlatListener*> listeners;
-
- /* Synchronous task checking for signals */
- task_s * checker;
-
- /* Channel mapping */
- static std::map<std::string, SignalChannel*> channels;
-
-public:
-
- SignalChannel(const std::string& id = "", bool pre_process = false);
- ~SignalChannel();
-
- void emit(const FlatSignal&);
-
- void connect(FlatListener*);
- void disconnect(FlatListener*);
-
- static SignalChannel * findChannel(const std::string&);
-
- void post_processing(void*);
-};
-
-/* Listener class */
-class FlatListener : virtual public FlatObject
-{
- std::list<std::string> filters;
-
- bool checkInFilters(const std::string&) const;
-
-protected:
-
- virtual void callback(FlatObject *sender, void *) = 0;
-
-public:
-
- FlatListener(const std::initializer_list<std::string>& filters = {});
- virtual ~FlatListener() {}
-
- void execute(const FlatSignal&);
-
- void addFilter(const std::string&);
- void removeFilter(const std::string&);
-
- bool connect(const std::string&);
- bool disconnect(const std::string&);
-};
-
-#endif
diff --git a/engine/include/flatsurface.h b/engine/include/flatsurface.h
index bc04385..3b64734 100644
--- a/engine/include/flatsurface.h
+++ b/engine/include/flatsurface.h
@@ -1,10 +1,10 @@
#ifndef __FLATSURFACE_H__
#define __FLATSURFACE_H__
-#include "flatobject.h"
+#include "object.hpp"
#include <SDL2/SDL.h>
-class FlatSurface : public FlatObject
+class FlatSurface : public flat::core::object
{
SDL_Surface * surface;
SDL_Surface * parent;
@@ -16,7 +16,7 @@ class FlatSurface : public FlatObject
public:
- FlatSurface(const char *filename, Uint32 format = SDL_PIXELFORMAT_RGBA32, SDL_Surface *parent = 0);
+ FlatSurface(const char *filename, uint32_t format = SDL_PIXELFORMAT_RGBA32, SDL_Surface *parent = 0);
FlatSurface(SDL_Surface *surface, SDL_Surface *parent = 0);
FlatSurface(const FlatSurface&);
@@ -47,7 +47,7 @@ public:
void blit();
- static SDL_Surface * loadOptimizedSurface(const char* filename, Uint32 format);
+ static SDL_Surface * loadOptimizedSurface(const char* filename, uint32_t format);
static SDL_Surface * copySurface(SDL_Surface*);
};
diff --git a/engine/include/flatwindow.h b/engine/include/flatwindow.h
index 11d7134..c03a3a9 100644
--- a/engine/include/flatwindow.h
+++ b/engine/include/flatwindow.h
@@ -26,7 +26,7 @@ struct window_status
unsigned char focus:1;
};
-#include "flatobject.h"
+#include "object.hpp"
#include "serial/keyfocusable.h"
class SDL_Window;
@@ -34,7 +34,7 @@ class FlatLayer;
class SDL_KeyEvent;
-class FlatWindow : virtual public FlatObject, public KeyFocusable
+class FlatWindow : virtual public flat::core::object, public KeyFocusable
{
std::string title;
window_status status;
@@ -91,7 +91,7 @@ public:
void setWindowStatus(window_status);
- static Uint32 winstatus_to_flags(window_status);
+ static uint32_t winstatus_to_flags(window_status);
};
#endif
diff --git a/engine/include/object.hpp b/engine/include/object.hpp
new file mode 100644
index 0000000..1992d2a
--- /dev/null
+++ b/engine/include/object.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <list>
+#include <vector>
+#include <string>
+#include <initializer_list>
+
+#include "types.hpp"
+
+namespace flat
+{
+ namespace core
+ {
+ class object;
+ }
+}
+
+class flat::core::object
+{
+ std::string id;
+
+ /* Common list of objects */
+ static std::list<object*> all_objects;
+
+public:
+
+ object();
+ ~object();
+
+ void set_id(const std::string&);
+
+ const std::string& get_id() const;
+
+ /* Static accessors to allObject */
+
+ static bool is_allocated(object*);
+
+ static std::vector<object*>& get_by_id(const std::string& id, std::vector<object*>&);
+
+ static std::string random_id(uint8_t length = 8);
+};
+
diff --git a/engine/include/serial/focusable.h b/engine/include/serial/focusable.h
index 6478ed4..4880ff8 100644
--- a/engine/include/serial/focusable.h
+++ b/engine/include/serial/focusable.h
@@ -1,13 +1,13 @@
#ifndef __FOCUSABLE_H__
#define __FOCUSABLE_H__
-#include "flatobject.h"
-#include "types.h"
+#include "object.hpp"
+#include "types.hpp"
class task_s;
union SDL_Event;
-class Focusable : virtual public FlatObject
+class Focusable : virtual public flat::core::object
{
bool focused;
@@ -19,7 +19,7 @@ protected:
virtual void serial_cb(const SDL_Event*) = 0;
/* Event stack specification */
- virtual Uint32 stackID() const = 0;
+ virtual uint32_t stackID() const = 0;
public:
diff --git a/engine/include/serial/keyfocusable.h b/engine/include/serial/keyfocusable.h
index c97c791..44c1f1b 100644
--- a/engine/include/serial/keyfocusable.h
+++ b/engine/include/serial/keyfocusable.h
@@ -10,7 +10,7 @@ class KeyFocusable : virtual public Focusable
virtual void serial_cb(const SDL_Event*) override;
- virtual Uint32 stackID() const override;
+ virtual uint32_t stackID() const override;
protected:
diff --git a/engine/include/signal.hpp b/engine/include/signal.hpp
new file mode 100644
index 0000000..db6638b
--- /dev/null
+++ b/engine/include/signal.hpp
@@ -0,0 +1,112 @@
+#pragma once
+
+#include <map>
+#include <list>
+#include <set>
+#include <initializer_list>
+#include "object.hpp"
+#include "task.hpp"
+#include "types.h"
+#include <functional>
+
+namespace flat
+{
+ namespace core
+ {
+ class signal;
+ class channel;
+ }
+}
+
+class flat::core::signal : virtual public flat::core::object
+{
+
+public:
+
+ flat::core::object * sender;
+ priority prior;
+
+ signal( flat::core::object * sender,
+ const std::string& id = "",
+ priority prior = 5);
+
+ /* Alias to flat::core::channel::emit() */
+ bool emit(const std::string& channel) const;
+
+ enum class priority : uint8_t
+ {
+ instant = 0,
+ highest,
+ high,
+ none,
+ low,
+ lowest
+ };
+};
+
+
+/* Channel class */
+class flat::core::channel : virtual public flat::core::object
+{
+ /* Post processing signal stacking */
+ stack_t stack;
+
+ /* Listeners list */
+ std::list<flat::core::listener> listeners;
+
+ /* Synchronous task checking for signals */
+ task_s * checker;
+
+ /* Channel mapping */
+ static std::map<std::string, channel*> channels;
+
+public:
+
+ flat::core::channel(const std::string& id = "", flat::core::task::priority prior = flat::core::task::priority::none);
+ ~flat::core::channel();
+
+ void emit(const flat::core::signal&);
+
+ void connect(flat::core::listener_s*);
+ void disconnect(flat::core::listener_s*);
+
+ static flat::core::channel * find_channel(const std::string&);
+
+ void post_processing(void*);
+
+ /* Functor for order comparison */
+ struct sig_prior_cmp {
+
+ bool operator()(const flat::core::signal&, const flat::core::signal&) const;
+ };
+
+ typedef std::set<flat::core::signal, sig_prior_cmp> stack_t;
+};
+
+/* Listener class */
+class flat::core::listener : virtual public flat::core::object
+{
+ std::list<std::string> filters;
+
+ bool check_in_filters(const std::string&) const;
+
+ std::function<void(const flat::core::object*)> m_callback;
+
+ flat::core::channel * parent = 0;
+
+public:
+
+ listener( std::function<void()> m_callback,
+ const std::initializer_list<std::string>& filters = {});
+
+ ~listener();
+
+ void add_filter(const std::string&);
+ void remove_filter(const std::string&);
+
+ bool connect(const std::string&);
+ bool disconnect(const std::string&);
+
+ void invoke(const flat::core::signal&);
+};
+
diff --git a/engine/include/types.h b/engine/include/types.hpp
index 003c114..436cc7c 100644
--- a/engine/include/types.h
+++ b/engine/include/types.hpp
@@ -3,7 +3,14 @@
/* Flatland types */
-class FlatObject;
+namespace flat
+{
+ namespace core
+ {
+ class object;
+ }
+
+}
class FlatActor;
class FlatSprite;
@@ -26,8 +33,8 @@ class task_s;
/* SDL types */
-typedef unsigned char Uint8;
-typedef unsigned int Uint32;
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
struct SDL_Surface;
struct SDL_Rect;
diff --git a/engine/keyfocusable.cpp b/engine/keyfocusable.cpp
index 39f4b01..29271dc 100644
--- a/engine/keyfocusable.cpp
+++ b/engine/keyfocusable.cpp
@@ -6,7 +6,7 @@ void KeyFocusable::serial_cb(const SDL_Event *event)
key_cb(&event->key);
}
-Uint32 KeyFocusable::stackID() const
+uint32_t KeyFocusable::stackID() const
{
// Set SDL_KEYDOWN by default
return SDL_KEYDOWN;
diff --git a/engine/object.cpp b/engine/object.cpp
new file mode 100644
index 0000000..990c403
--- /dev/null
+++ b/engine/object.cpp
@@ -0,0 +1,62 @@
+#include "object.hpp"
+
+#include <stdlib.h>
+
+using namespace std;
+using namespace flat::core;
+
+list<object*> object::all_objects;
+
+object::object()
+{
+ /* Collect this object */
+ object::all_objects.push_back(this);
+}
+
+object::~object()
+{
+ /* Eliminate this object reference */
+ object::all_objects.remove(this);
+}
+
+void object::set_id(const string& id)
+{
+ this->id = id;
+}
+
+const string& object::get_id() const
+{
+ return id;
+}
+
+string object::random_id(uint8_t length) {
+
+ string out;
+
+ for (Uint8 i = 0; i < length; ++i)
+ out += (char)(rand() % 93 + 33);
+
+ return out;
+}
+
+bool object::is_allocated(object *obj)
+{
+ for (object * o : object::all_objects)
+ {
+ if (o == obj)
+ return true;
+ }
+
+ return false;
+}
+
+vector<object*>& object::get_by_id(const string& id, vector<object*>& l)
+{
+ for (object * obj : object::all_objects)
+ {
+ if (id == obj->getID())
+ l.push_back(obj);
+ }
+
+ return l;
+}
diff --git a/engine/signal.cpp b/engine/signal.cpp
new file mode 100644
index 0000000..98f133e
--- /dev/null
+++ b/engine/signal.cpp
@@ -0,0 +1,191 @@
+#include "signal.hpp"
+#include "task.hpp"
+
+using namespace std;
+using namespace flat::core;
+
+bool channel::sig_prior_cmp::operator()(const signal& s, const signal& g) const
+{
+ return s.prior <= g.prior;
+}
+
+map<string, channel*> channel::channels;
+
+channel::channel(const string& id, task::priority prior)
+{
+ channel * other = find_channel(id);
+
+ if (!other)
+ //TODO throw exception
+ ;
+
+ /* Initialize task, post-process, fifth priority */
+ checker = new task<channel>( this,
+ &channel::post_processing,
+ 0,
+ prior);
+
+ string ID = (id.empty()) ? object::random_id() : id;
+
+ set_id(ID);
+
+ channels.insert(pair<string, channel*>(ID, this));
+}
+
+channel::~channel()
+{
+ channels.erase(get_id());
+
+ /* Finalize task */
+ delete checker;
+}
+
+void channel::emit(const signal& sig)
+{
+ if (!sig.priority) {
+
+ /* Execute immediately */
+ for (auto lis : listeners)
+ lis->execute(sig);
+
+ } else
+ /* Insert in order of priority */
+ stack.insert(sig);
+}
+
+void channel::connect(listener* l)
+{
+ /* Control not to double */
+ for (auto lis : listeners)
+ {
+ if (lis == l)
+ return;
+ }
+
+ listeners.push_back(l);
+}
+
+void channel::disconnect(listener* l)
+{
+ listeners.remove(l);
+}
+
+
+channel * channel::find_channel(const string& id)
+{
+ if (id.empty())
+ return 0;
+
+ auto it = channels.find(id);
+
+ return (it == channels.end()) ? 0 : (*it).second;
+}
+
+void channel::post_processing(void*)
+{
+ if (!stack.empty()) {
+
+ /* for each listener_s, catch signal */
+ for (const auto& signal : stack)
+ {
+ for (auto l : listeners)
+ l->execute(signal);
+ }
+
+ stack.clear();
+ }
+}
+
+
+
+/* signal class */
+
+signal::signal(flat::core::object *sender, const string& id, void *data, Uint8 priority)
+ : sender(sender), data(data), priority(priority)
+{
+ set_id(id);
+}
+
+bool signal::emit(const string& channel) const
+{
+ channel * chan = channel::find_channel(channel);
+
+ if (!chan)
+ return false;
+
+ /* Finally emit in channel */
+ chan->emit(*this);
+
+ return true;
+}
+
+
+
+/* listener_s class */
+
+listener::listener( std::function<void()> m_callback,
+ const std::initializer_list<std::string>& filters)
+
+ : m_callback(m_callback), filters(filters)
+{
+
+}
+
+listener::~listener()
+{
+ if (parent != 0)
+ parent->disconnect(this);
+}
+
+bool listener::check_in_filters(const std::string& filter) const
+{
+ for (const auto& f : filters)
+ {
+ if (filter == f)
+ return true;
+ }
+
+ return false;
+}
+
+void listener::add_filter(const std::string& f)
+{
+ filters.push_back(f);
+}
+
+void listener::remove_filter(const std::string& f)
+{
+ filters.remove(f);
+}
+
+bool listener::connect(const std::string& chan)
+{
+ channel * c = channel::find_channel(chan);
+
+ if (!c)
+ c->connect(this);
+
+ parent = c;
+
+ return c != 0;
+}
+
+bool listener_s::disconnect(const std::string& chan)
+{
+ channel * c = channel::find_channel(chan);
+
+ if (!c)
+ c->connect(this);
+
+ parent = 0;
+
+ return c != 0;
+}
+
+void listener::invoke(const flat::core::signal&)
+{
+ if ((!sig.get_id().empty() && check_in_filters(sig.get_id())) ||
+ (sig.get_id().empty() && filters.empty()))
+ m_callback(sig.sender);
+}
+
diff --git a/test/test3.cpp b/test/test3.cpp
new file mode 100644
index 0000000..0edd682
--- /dev/null
+++ b/test/test3.cpp
@@ -0,0 +1,120 @@
+#include "flatland.h"
+#include "flatwindow.h"
+#include "exceptions/forcequit.h"
+
+#include "serial/keyfocusable.h"
+#include <SDL2/SDL.h>
+
+#include <iostream>
+#include <string>
+
+#include "flatsignal.h"
+
+using namespace std;
+
+int count = 0;
+
+void loop(float);
+
+class KeyPrinter : public KeyFocusable
+{
+ virtual void key_cb(const SDL_KeyboardEvent* key) override
+ {
+ string msg = (key->type == SDL_KEYDOWN) ? "pressed" : "released";
+ cout << "KeyPrinter: key " << (char)key->keysym.sym << " " << msg << endl;
+ };
+
+public:
+
+ using KeyFocusable::KeyFocusable;
+};
+
+class KeyCaller : public KeyFocusable
+{
+ int counter;
+ char last;
+
+ virtual void key_cb(const SDL_KeyboardEvent* key) override
+ {
+ if (key->type == SDL_KEYDOWN) {
+
+ char c = key->keysym.sym;
+
+ if (c == last)
+ ++counter;
+ else {
+ last = c;
+ counter = 0;
+ cout << "KeyCaller: Counter set to 0" << endl;
+ }
+ }
+
+ if (counter == 20)
+ {
+ FlatSignal signal(this, "char", (void*)&last);
+ signal.emit("alpha");
+
+ cout << "KeyCaller: 20 times reached" << endl;
+ cout << "KeyCaller: sending " << last << endl;
+ }
+
+ if (counter == 50)
+ {
+ cout << "KeyCaller: 50 times pressed " << last << endl;
+
+ /* Exit application */
+ FlatSignal signal(this, "quit");
+ signal.emit("core");
+ }
+ };
+
+public:
+
+ KeyCaller() : counter(0), last('\0')
+ {
+ setID("CALLER");
+ }
+};
+
+class TwentyListener : public FlatListener
+{
+ virtual void callback(FlatObject *sender, void *data) override
+ {
+ char c = *(char*)data;
+ cout << "TwentyListener: received " << c << " from " << sender->getID() << endl;
+ }
+
+public:
+
+ TwentyListener() : FlatListener({"char"}) {}
+};
+
+KeyPrinter printer;
+KeyCaller caller;
+TwentyListener twlistener;
+
+SignalChannel alpha("alpha");
+
+int main()
+{
+ FlatWindow win(600, 900, "Test 3");
+ flat_status status;
+
+ /* Connect listener to alpha channel */
+ alpha.connect(&twlistener);
+
+ init_flatland(&win, loop, status, 60);
+
+ return 0;
+}
+
+void loop(float dt)
+{
+ ++count;
+
+ if (count == 10000)
+ throw ForceQuit("10000 steps reached");
+
+ //cout << "Loop number: " << count << endl;
+}
+