summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorancarola <raffaele.ancarola@epfl.ch>2019-01-25 22:05:15 +0100
committerancarola <raffaele.ancarola@epfl.ch>2019-01-25 22:05:15 +0100
commitfe75db9167f4327d2bb2353f94d84047666bb440 (patch)
treea1f67e5fff1d1f0458ae1ae4fb6e9d4ebf57b58c
parentUpdate to make configure.py to build deps, instead of build.ninja (diff)
downloadflatland-fe75db9167f4327d2bb2353f94d84047666bb440.tar.gz
flatland-fe75db9167f4327d2bb2353f94d84047666bb440.zip
Core channel in flatland and signal test
-rw-r--r--engine/flatland.cpp104
-rw-r--r--engine/include/core/object.hpp12
-rw-r--r--engine/include/core/signal.hpp15
-rw-r--r--engine/include/flatland.hpp9
-rw-r--r--engine/include/object.hpp9
-rw-r--r--engine/signal.cpp13
m---------lib/libmm0
m---------lib/libwrapsdl20
-rw-r--r--test/signal_test.cpp101
9 files changed, 224 insertions, 39 deletions
diff --git a/engine/flatland.cpp b/engine/flatland.cpp
index f761473..fdfa6fc 100644
--- a/engine/flatland.cpp
+++ b/engine/flatland.cpp
@@ -12,23 +12,52 @@ using namespace flat;
#include "core/task.hpp"
#include "core/signal.hpp"
+#include "object.hpp"
#include "window.hpp"
#include "exception.hpp"
#include "exceptions/forcequit.hpp"
-float flatland_dt;
+/* Global fields definitions */
-set<flat::core::object*> objects;
+float flatland_dt;
FlatWindow * window = 0;
-gameloop loop_function;
-
flat_status status;
float fps;
float fps_pause = 5;
+core::job mainsync_job;
+
+core::channel core_chan("core");
+
+core::listener::ptr quit_listener;
+core::listener::ptr print_listener;
+
+/* channels listeners callback */
+
+void quit_callback(object *sender, signal::package)
+{
+ cout << "Flatland: quit request attempted" << endl;
+ flat::quit();
+}
+
+void print_callback(object *sender, signal::package p)
+{
+ const char * out = p.get<const char>();
+ string * sout = p.get<string>();
+
+ if (!out)
+ cout << "Flatland: " << out << endl;
+ else if (!sout)
+ cout << "Flatland: " << sout << endl;
+
+ // else fail silently
+}
+
+/* Functions implementation */
+
uint32_t status_to_flags(const flat_status& s)
{
uint32_t flags = 0;
@@ -57,16 +86,67 @@ uint32_t status_to_flags(const flat_status& s)
return flags;
}
+/* Accessors */
+
+channel& core_channel()
+{
+ return core_chan;
+}
+
+job& main_job()
+{
+ return mainsync_job;
+}
+
+/* Main loop */
+
int init_flatland(FlatWindow* w, gameloop loop, const flat_status& s, float _fps)
{
cout << "Flatland: Initializing flatland" << endl;
+ // init core channel
+
+ cout << "Flatland: Initializing core channel" << endl;
+
+ core_chan.start(priority_t::max);
+
+ if (!core_chan.map()) {
+
+ cout << "Flatland: Could not map 'core' channel" << endl;
+ cout << "Flatland: Do not call another channel 'core' before flatland initialization" << endl;
+ cout << "Flatland: Aborting" << endl;
+ return -1;
+ }
+
+ // bind listeners
+
+ quit_listener = core_chan.connect(&quit_callback, {"quit"});
+
+ // control if quit was not already connected
+ if (!quit_listener) {
+
+ cout << "Flatland: Could not connect 'quit' listener" << endl;
+ cout << "Flatland: Do not connect to core channel another listener with filter name 'quit' before flatland initialization" << endl;
+ cout << "Flatland: Aborting" << endl;
+ return -1;
+ }
+
+ print_listener = core_chan.connect(&print_callback, {"print"});
+
+ // control if print was not already connected
+ if (!print_listener) {
+
+ cout << "Flatland: Could not connect 'print' listener" << endl;
+ cout << "Flatland: Do not connect to core channel another listener with filter name 'print' before flatland initialization" << endl;
+ cout << "Flatland: Aborting" << endl;
+ return -1;
+ }
+
// init variables
cout << "Flatland: Initializing window" << endl;
window = w;
- loop_function = loop;
status = s;
fps = _fps;
@@ -106,16 +186,8 @@ int init_flatland(FlatWindow* w, gameloop loop, const flat_status& s, float _fps
try {
- try {
-
- /* Execute loop function */
- loop_function(flatland_dt);
-
- } catch (const exception &e) {
-
- cerr << "Flatland: exception thrown while executing loop" << endl;
- cerr << e.what() << endl;
- }
+ /* Invoke main sync job tasks */
+ mainsync_job();
} catch (const ForceQuit& f) {
@@ -146,7 +218,7 @@ int init_flatland(FlatWindow* w, gameloop loop, const flat_status& s, float _fps
return status.error;
}
-void quit_flatland()
+void quit()
{
status.running = 0;
status.loop = 0;
diff --git a/engine/include/core/object.hpp b/engine/include/core/object.hpp
deleted file mode 100644
index cd5da5e..0000000
--- a/engine/include/core/object.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-namespace flat
-{
- namespace core
- {
- struct object
- {
- // it exists
- };
- }
-}
diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp
index 8a3d639..7d91150 100644
--- a/engine/include/core/signal.hpp
+++ b/engine/include/core/signal.hpp
@@ -4,7 +4,6 @@
#include <list>
#include <set>
#include <initializer_list>
-#include "object.hpp"
#include "task.hpp"
#include "types.hpp"
#include <functional>
@@ -14,6 +13,8 @@
namespace flat
{
+ class object;
+
namespace core
{
@@ -70,8 +71,7 @@ namespace flat
template<typename R, typename T>
static ptr create( R T::*mf,
T& obj,
- const std::initializer_list<std::string>& filters = {})
- {
+ const std::initializer_list<std::string>& filters = {}) {
return std::make_shared<listener>(std::bind(mf, obj), filters);
}
@@ -118,10 +118,17 @@ namespace flat
bool connect(listener* l);
void disconnect(listener* l);
+
+ listener::ptr connect(listener::callback f, const std::initializer_list<std::string>& filters = {});
+
+ template<typename R, typename T>
+ inline listener::ptr connect(R T::*mf, T& obj, const std::initializer_list<std::string>& filters = {}) {
+ return connect(std::bind(mf, obj));
+ }
static ptr find(const std::string&);
- static ptr create(const std::string& id, priority_t prior);
+ static ptr create(const std::string& id, priority_t prior = priority_t::none);
void check_and_call();
};
diff --git a/engine/include/flatland.hpp b/engine/include/flatland.hpp
index 331093b..c0216d8 100644
--- a/engine/include/flatland.hpp
+++ b/engine/include/flatland.hpp
@@ -5,8 +5,6 @@ namespace flat {
class FlatWindow;
-typedef void (*gameloop)(float);
-
struct flat_status
{
@@ -37,7 +35,7 @@ struct flat_status
unsigned char loop:1;
};
-int init_flatland(FlatWindow*, gameloop, const flat_status&, float fps = 60);
+int init_flatland(FlatWindow*, const flat_status&, float fps = 60);
void quit_flatland();
namespace core {
@@ -49,12 +47,11 @@ namespace core {
/* Engine channels */
-core::channel& core_chan();
-core::channel& error_chan();
+core::channel& core_channel();
/* Main job access */
-core::job& game_job();
+core::job& main_job();
/* Window and status accessors */
diff --git a/engine/include/object.hpp b/engine/include/object.hpp
new file mode 100644
index 0000000..70a7a2d
--- /dev/null
+++ b/engine/include/object.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+namespace flat
+{
+ struct object
+ {
+ // it exists
+ };
+}
diff --git a/engine/signal.cpp b/engine/signal.cpp
index 8546094..0e1935d 100644
--- a/engine/signal.cpp
+++ b/engine/signal.cpp
@@ -1,4 +1,5 @@
#include "core/signal.hpp"
+#include "object.hpp"
#include <functional>
#include "flatland.hpp"
@@ -21,7 +22,7 @@ channel::~channel()
void channel::start(priority_t prior)
{
// Initialize task
- checker = flat::game_job().delegate_task(&channel::check_and_call, *this, prior);
+ checker = flat::main_job().delegate_task(&channel::check_and_call, *this, prior);
}
bool channel::map()
@@ -82,6 +83,16 @@ void channel::disconnect(listener* l)
disconnect(pt);
}
+listener::ptr channel::connect(listener::callback f, const std::initializer_list<std::string>& filters)
+{
+ listener::ptr lis = std::make_shared<listener>(f, filters);
+
+ if (connect(lis))
+ return lis;
+
+ return nullptr;
+}
+
channel::ptr channel::create(const string& id, priority_t prior)
{
ptr out = std::make_shared<channel>(id);
diff --git a/lib/libmm b/lib/libmm
-Subproject ba03d198b82733043919fda918a80f4bb81800a
+Subproject e6595cf9c527e97198806c48aa0a14ae8e895e8
diff --git a/lib/libwrapsdl2 b/lib/libwrapsdl2
new file mode 160000
+Subproject 66bb51fa6148d6910da054bacd4fcbd2fa7b5ba
diff --git a/test/signal_test.cpp b/test/signal_test.cpp
new file mode 100644
index 0000000..2e17747
--- /dev/null
+++ b/test/signal_test.cpp
@@ -0,0 +1,101 @@
+#include "core/signal.hpp"
+#include "core/task.hpp"
+#include "object.h"
+#include "flatland.hpp"
+#include <iostream>
+
+using namespace std;
+using namespace flat::core;
+
+
+class sender : public object
+{
+ const char * message;
+ channel::ptr chan;
+
+public:
+
+ sender(const char * message, channel::ptr chan) : message(message), chan(chan)
+ {
+ }
+
+ void send()
+ {
+ signal msg(this, "", (void*)message);
+ chan->emit(msg);
+ }
+};
+
+void function_listener(const object*, signal::package msg)
+{
+ cout << "Funzione: " << msg.get<const char>() << endl;
+};
+
+class class_listener
+{
+
+ listener::ptr lis;
+
+public:
+
+ class_listener(channel::ptr chan)
+ {
+ lis = chan->connect(&class_listener::listen, *this);
+ }
+
+ void listen(const object*, signal::package)
+ {
+ cout << "Metodo" << msg.get<const char>() << endl;
+ }
+};
+
+/* Objects definition */
+
+channel::ptr alpha;
+sender * m_sender;
+class_listener * m_listener;
+listener::ptr f_listener;
+
+int count = 0;
+
+void lifeloop()
+{
+ if (!(count % 10))
+ cout << "Step: " << count << endl;
+
+ if (!(count % 40))
+ m_sender.send();
+
+ if (++count > 2000)
+ {
+ signal quit(0, "quit");
+
+ // quit request
+ flat::core_channel().emit(quit);
+ }
+}
+
+int main()
+{
+ FlatWindow win(600, 900, "Test 3");
+ flat_status status;
+
+ alpha = channel::create("alpha");
+
+ // create sender
+ m_sender = new sender("Ciao", alpha);
+ m_listener = new class_listener(alpha);
+
+ // Connect listener to alpha channel
+ f_listener = alpha.connect(&function_listener);
+
+ // bind counter task
+ task::ptr looptask = flat::main_job().delegate_task(&lifeloop);
+
+ init_flatland(&win, status, 60);
+
+ delete m_sender;
+ delete m_listener;
+
+ return 0;
+}