diff options
author | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-19 13:07:37 +0100 |
---|---|---|
committer | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-19 13:07:37 +0100 |
commit | 3922c797671cdc23d9233ff76909489e45fd0006 (patch) | |
tree | d385754f00159b93a8966fb5080a51dc2d0eb4a0 | |
parent | edas (diff) | |
download | flatland-3922c797671cdc23d9233ff76909489e45fd0006.tar.gz flatland-3922c797671cdc23d9233ff76909489e45fd0006.zip |
Test two completed successfully
-rw-r--r-- | engine/flatland.cpp | 57 | ||||
-rw-r--r-- | engine/flatobject.cpp | 25 | ||||
-rw-r--r-- | engine/flatserial.cpp | 76 | ||||
-rw-r--r-- | engine/flatsignal.cpp | 168 | ||||
-rw-r--r-- | engine/flatwindow.cpp | 14 | ||||
-rw-r--r-- | engine/focusable.cpp | 31 | ||||
-rw-r--r-- | engine/include/flatland.h | 8 | ||||
-rw-r--r-- | engine/include/flatobject.h | 11 | ||||
-rw-r--r-- | engine/include/flatserial.h | 38 | ||||
-rw-r--r-- | engine/include/flatsignal.h | 103 | ||||
-rw-r--r-- | engine/include/flatwindow.h | 6 | ||||
-rw-r--r-- | engine/include/serial/focusable.h (renamed from engine/include/focusable.h) | 25 | ||||
-rw-r--r-- | engine/include/serial/keyfocusable.h | 24 | ||||
-rw-r--r-- | engine/include/types.h | 3 | ||||
-rw-r--r-- | engine/keyfocusable.cpp | 14 | ||||
-rw-r--r-- | goals | 24 | ||||
-rw-r--r-- | test/main.cpp | 4 | ||||
-rwxr-xr-x | test/test | bin | 14248 -> 14248 bytes | |||
-rw-r--r-- | test/test1.cpp | 30 |
19 files changed, 537 insertions, 124 deletions
diff --git a/engine/flatland.cpp b/engine/flatland.cpp index d8c17f5..531d42c 100644 --- a/engine/flatland.cpp +++ b/engine/flatland.cpp @@ -10,6 +10,7 @@ using namespace std; #include "flattask.h" +#include "flatsignal.h" #include "flatwindow.h" float flatland_dt; @@ -17,6 +18,7 @@ float flatland_dt; set<FlatObject*> objects; FlatWindow * window = 0; +SignalChannel * core = 0; gameloop loop_function; @@ -53,17 +55,46 @@ Uint32 status_to_flags(const flat_status& s) return flags; } -int init_flatland(const FlatWindow& w, gameloop loop, const flat_status& s, float _fps) +/* Listen to simple quit calls */ +class QuitListener : public FlatListener { + virtual void callback(FlatObject*, void*) override + { + /* Order to quit */ + quit_flatland(); + } + +public: + + QuitListener() + { + addFilter("quit"); + core->connect(this); + } +}; + +int init_flatland(FlatWindow* w, gameloop loop, const flat_status& s, float _fps) +{ + cout << "Flatland: Initializing flatland" << endl; + + // Init core channel + + core = new SignalChannel("core"); + QuitListener quitter; + // init variables + + cout << "Flatland: Initializing window" << endl; - window = new FlatWindow(w); + window = w; loop_function = loop; status = s; fps = _fps; // init SDL + cout << "Flatland: Initializing SDL" << endl; + Uint32 flags = status_to_flags(s); if ( SDL_Init(flags | SDL_INIT_NOPARACHUTE) < 0) @@ -74,6 +105,7 @@ int init_flatland(const FlatWindow& w, gameloop loop, const flat_status& s, floa // init window + cout << "Flatland: Opening window" << endl; window->open(); /* Game loop */ @@ -83,6 +115,8 @@ int init_flatland(const FlatWindow& w, gameloop loop, const flat_status& s, floa clock_t delay = 0; + cout << "Flatland: Entering game-loop" << endl; + do { do { @@ -91,12 +125,12 @@ int init_flatland(const FlatWindow& w, gameloop loop, const flat_status& s, floa delay = clock(); - /* Execute tasks */ - task_s::executeAll(); - /* Execute loop function */ loop_function(flatland_dt); + /* Execute tasks */ + task_s::executeAll(); + SDL_Delay((Uint32) (1000.0f / fps)); delay -= clock(); @@ -107,8 +141,12 @@ int init_flatland(const FlatWindow& w, gameloop loop, const flat_status& s, floa } while(status.running); - delete window; - window = 0; + cout << "Flatland: destroying core channel" << endl; + + delete core; + core = 0; + + cout << "Flatland: quitting SDL" << endl; SDL_Quit(); @@ -126,3 +164,8 @@ flat_status flatland_status() return status; } +SignalChannel * getCoreChannel() +{ + return core; +} + diff --git a/engine/flatobject.cpp b/engine/flatobject.cpp index bfbff0b..a325942 100644 --- a/engine/flatobject.cpp +++ b/engine/flatobject.cpp @@ -1,6 +1,6 @@ #include "flatobject.h" -#include <string.h> +#include <stdlib.h> using namespace std; @@ -18,15 +18,24 @@ FlatObject::~FlatObject() FlatObject::allObjects.remove(this); } -void FlatObject::setID(const char *id) +void FlatObject::setID(const string& id) { - strncpy(this->id, id, 31); - this->id[31] = '\0'; + this->id = id; } -const char* FlatObject::getID() const +const string& FlatObject::getID() const { - return &id[0]; + 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) @@ -40,11 +49,11 @@ bool FlatObject::isAllocated(FlatObject *obj) return false; } -vector<FlatObject*>& FlatObject::getByID(const char *id, vector<FlatObject*>& l) +vector<FlatObject*>& FlatObject::getByID(const string& id, vector<FlatObject*>& l) { for (FlatObject * obj : FlatObject::allObjects) { - if (!strcmp(id, obj->getID())) + if (id == obj->getID()) l.push_back(obj); } diff --git a/engine/flatserial.cpp b/engine/flatserial.cpp index d725d30..25eafbe 100644 --- a/engine/flatserial.cpp +++ b/engine/flatserial.cpp @@ -1,22 +1,84 @@ #include "flatserial.h" +#include "flattask.h" -#include <vector> - -using namespace std; - -void process_events() +SDL_EventCollector::SDL_EventCollector() { + checker = new FlatTask<SDL_EventCollector>(this, &SDL_EventCollector::collect, 0); +} +SDL_EventCollector::~SDL_EventCollector() +{ + delete checker; } -void registerFocusable(Focusable*) +void SDL_EventCollector::collect(void*) { + SDL_Event event; + + while ( SDL_PollEvent(&event) ) + { + switch(event.type) + { + + /* Keyboard */ + case SDL_KEYDOWN: + keyboard.push_back(event); + break; + + case SDL_KEYUP: + keyboard.push_back(event); + break; + + /* Window */ + case SDL_WINDOWEVENT: + window.push_back(event); + break; + /* Quit */ + case SDL_QUIT: + quit.push_back(event); + break; + + /* User */ + case SDL_USEREVENT: + user.push_back(event); + break; + } + + // TODO other events + } } -void unregisterFocusable(Focusable*) +const std::vector<SDL_Event>& SDL_EventCollector::getStack(Uint32 id) const { + switch(id) + { + { + + /* Keyboard */ + case SDL_KEYDOWN: + return keyboard; + + case SDL_KEYUP: + return keyboard; + + /* Window */ + case SDL_WINDOWEVENT: + return window; + + /* Quit */ + case SDL_QUIT: + return quit; + + /* User */ + case SDL_USEREVENT: + return user; + + } + // TODO other events + } } +SDL_EventCollector * FlatSerial::collector = new SDL_EventCollector(); diff --git a/engine/flatsignal.cpp b/engine/flatsignal.cpp index 1503c24..8d66ae1 100644 --- a/engine/flatsignal.cpp +++ b/engine/flatsignal.cpp @@ -1,17 +1,175 @@ #include "flatsignal.h" +#include "flattask.h" using namespace std; -vector<FlatSignal> FlatSignal::sig_stack; +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) +{ + SignalChannel * other = findChannel(id); + + if (!other) + //TODO throw exception + ; + + /* Initialize task */ + checker = new FlatTask<SignalChannel>(this, &SignalChannel::post_processing, 0); + + 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) { -FlatSignal::FlatSignal(int type, void *data) - : type(type), data(data) + /* 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); } -FlatSignal::emit(const FlatSignal &signal) +void SignalChannel::disconnect(FlatListener* l) { - FlatSignal::sig_stack.push_back(signal); + 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, void *data, Uint8 priority) + : sender(sender), data(data), priority(priority) +{ +} + +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()) + { + if (!checkInFilters(sig.getID())) + return; + } + + 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/flatwindow.cpp b/engine/flatwindow.cpp index d1d444e..cbff905 100644 --- a/engine/flatwindow.cpp +++ b/engine/flatwindow.cpp @@ -3,6 +3,7 @@ #include <SDL2/SDL.h> #include <iostream> #include "flatlayer.h" +#include "flatsignal.h" using namespace std; @@ -155,17 +156,18 @@ void FlatWindow::setWindowStatus(window_status status) this->status = status; } -void FlatWindow::serial_cb(const SDL_Event &event) +void FlatWindow::key_cb(const SDL_KeyboardEvent *event) { // TODO Default escape exits - switch (event.type) + if (event->type == SDL_KEYDOWN && event->keysym.sym == SDLK_ESCAPE) { - case SDL_KEYDOWN: + /* Close window */ + close(); - if (event.key.keysym.sym == SDLK_ESCAPE) - close(); // TODO not enough - break; + /* Say flatland to quit */ + FlatSignal quit(this, 0, 0xff); + quit.emit("core"); } } diff --git a/engine/focusable.cpp b/engine/focusable.cpp index 4a651e6..df26ea9 100644 --- a/engine/focusable.cpp +++ b/engine/focusable.cpp @@ -1,29 +1,6 @@ -#include "focusable.h" +#include "serial/focusable.h" #include "flattask.h" -#include "SDL2/SDL.h" - - -SDL_EventCollector::SDL_EventCollector() -{ - checker = new FlatTask<SDL_EventCollector>(this, &SDL_EventCollector::collect, 0); -} - -SDL_EventCollector::~SDL_EventCollector() -{ - delete checker; -} - -void SDL_EventCollector::collect(void*) -{ - SDL_Event event; - - while ( SDL_PollEvent(&event) ) - stack.push_back(event); -} - - - -SDL_EventCollector * Focusable::collector = new SDL_EventCollector(); +#include "flatserial.h" Focusable::Focusable(bool focused) : focused(focused) { @@ -47,7 +24,7 @@ bool Focusable::isFocused() const void Focusable::serial_precall(void*) { - for (auto event : Focusable::collector->stack) - serial_cb(event); + for (auto event : FlatSerial::collector->getStack(stackID())) + serial_cb(&event); } diff --git a/engine/include/flatland.h b/engine/include/flatland.h index 18b1a89..27d2d12 100644 --- a/engine/include/flatland.h +++ b/engine/include/flatland.h @@ -35,9 +35,15 @@ struct flat_status unsigned char loop:1; }; -int init_flatland(const FlatWindow&, gameloop, const flat_status&, float fps = 60); +int init_flatland(FlatWindow*, gameloop, const flat_status&, float fps = 60); void quit_flatland(); +/* Core channel */ + +class SignalChannel; + +SignalChannel * getCoreChannel(); + /* Window and status accessors */ FlatWindow * getFlatWindow(); diff --git a/engine/include/flatobject.h b/engine/include/flatobject.h index fe7b107..7ad1ddd 100644 --- a/engine/include/flatobject.h +++ b/engine/include/flatobject.h @@ -3,13 +3,14 @@ #include <list> #include <vector> +#include <string> #include <initializer_list> #include "types.h" class FlatObject { - char id[32]; + std::string id; /* Common list of objects */ static std::list<FlatObject*> allObjects; @@ -19,15 +20,17 @@ public: FlatObject(); ~FlatObject(); - void setID(const char*); + void setID(const std::string&); - const char* getID() const; + const std::string& getID() const; /* Static accessors to allObject */ static bool isAllocated(FlatObject*); - static std::vector<FlatObject*>& getByID(const char *id, std::vector<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 b95413d..41c6b97 100644 --- a/engine/include/flatserial.h +++ b/engine/include/flatserial.h @@ -1,14 +1,42 @@ #ifndef __FLATSERIAL_H__ #define __FLATSERIAL_H__ -/* SDL serial events handling */ +#include "types.h" +#include <vector> +#include "SDL2/SDL.h" -class Focusable; +union SDL_Event; +class task_s; -void process_events(); +struct SDL_EventCollector +{ + task_s * checker; + + /* Keyboard event */ + std::vector<SDL_Event> keyboard; -void registerFocusable(Focusable*); + /* Window resize or iconize event */ + std::vector<SDL_Event> window; -void unregisterFocusable(Focusable*); + /* Quit notification */ + std::vector<SDL_Event> quit; + + /* Custom events: useful for signals */ + std::vector<SDL_Event> user; + + // TODO other events + + SDL_EventCollector(); + ~SDL_EventCollector(); + + void collect(void*); + + const std::vector<SDL_Event>& getStack(Uint32 id) const; +}; + +namespace FlatSerial { + + extern SDL_EventCollector * collector; +} #endif diff --git a/engine/include/flatsignal.h b/engine/include/flatsignal.h index 6ec837a..fa403e2 100644 --- a/engine/include/flatsignal.h +++ b/engine/include/flatsignal.h @@ -1,60 +1,97 @@ #ifndef __FLAT_SIGNAL_H__ #define __FLAT_SIGNAL_H__ -#include <vector> #include <map> +#include <list> +#include <set> +#include <initializer_list> #include "flatobject.h" +#include "types.h" -class task_s; +/* Post-process signal delivery when it's emitted */ +#define FSIG_PRIOR_INSTANT 0 -struct FlatSignal : virtual public FlatObject +/* Process and emitted signal instantaneously */ +#define FSIG_PRIOR_DEFAULT 5 + +class FlatSignal : virtual public FlatObject { - const int type; + +public: + + FlatObject * sender; void * data; + Uint8 priority; - FlatSignal(int type, void *data); + FlatSignal(FlatObject * sender, void *data = 0, Uint8 priority = 5); - static emit(const FlatSignal&); - static std::vector<FlatSignal> sig_stack; + /* Alias to SignalChannel::emit() */ + bool emit(const std::string& channel) const; }; -template <class T> -class FlatListener : virtual public FlatObject -{ - typedef void (T::*callback_t)(void*); +class FlatListener; - task_s * listener; +/* Functor for order comparison */ +struct sig_prior_cmp { + + bool operator()(const FlatSignal&, const FlatSignal&) const; +}; - void checkSignal(void*) - { - for (auto signal : FlatSignal::sig_stack) - { - callback_t cb; +typedef std::set<FlatSignal, sig_prior_cmp> SignalStack; - if (cb = checkmap.find(signal.type)) - cb(signal.data); - } - } +/* Channel class */ +class SignalChannel : virtual public FlatObject +{ + /* Post processing signal stacking */ + SignalStack stack; - std::map<int, callback_t> checkmap; + /* Listeners list */ + std::list<FlatListener*> listeners; -public: + /* Synchronous task checking for signals */ + task_s * checker; - FlatListener() - { + /* Channel mapping */ + static std::map<std::string, SignalChannel*> channels; + +public: - } + SignalChannel(const std::string& id = ""); + ~SignalChannel(); - ~FlatListener() - { + void emit(const FlatSignal&); - } + void connect(FlatListener*); + void disconnect(FlatListener*); + + static SignalChannel * findChannel(const std::string&); - connect(int type, callback_t cb) - { - checkmap.insert(std::make_pair(type, cb)); - } + 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/flatwindow.h b/engine/include/flatwindow.h index 8c3d5bf..eb113c1 100644 --- a/engine/include/flatwindow.h +++ b/engine/include/flatwindow.h @@ -27,14 +27,14 @@ struct window_status }; #include "flatobject.h" -#include "focusable.h" +#include "serial/keyfocusable.h" class SDL_Window; class FlatLayer; class SDL_KeyEvent; -class FlatWindow : public FlatObject, public Focusable +class FlatWindow : public FlatObject, virtual public KeyFocusable { std::string title; window_status status; @@ -45,7 +45,7 @@ class FlatWindow : public FlatObject, public Focusable FlatLayer * main_layer; - void serial_cb(const SDL_Event&) override; + void key_cb(const SDL_KeyboardEvent*) override; // TODO window calls //protected: diff --git a/engine/include/focusable.h b/engine/include/serial/focusable.h index b70357b..325f84b 100644 --- a/engine/include/focusable.h +++ b/engine/include/serial/focusable.h @@ -1,21 +1,10 @@ #ifndef __FOCUSABLE_H__ #define __FOCUSABLE_H__ -#include <vector> +#include "types.h" -union SDL_Event; class task_s; - -struct SDL_EventCollector -{ - task_s * checker; - std::vector<SDL_Event> stack; - - SDL_EventCollector(); - ~SDL_EventCollector(); - - void collect(void*); -}; +union SDL_Event; class Focusable { @@ -23,7 +12,13 @@ class Focusable task_s * event_trigger; - static SDL_EventCollector * collector; +protected: + + /* Callback to event */ + virtual void serial_cb(const SDL_Event*) = 0; + + /* Event stack specification */ + virtual Uint32 stackID() const = 0; public: @@ -31,8 +26,6 @@ public: virtual ~Focusable(); - virtual void serial_cb(const SDL_Event&) = 0; - void setFocused(bool flag); bool isFocused() const; diff --git a/engine/include/serial/keyfocusable.h b/engine/include/serial/keyfocusable.h index e69de29..02b3361 100644 --- a/engine/include/serial/keyfocusable.h +++ b/engine/include/serial/keyfocusable.h @@ -0,0 +1,24 @@ +#ifndef __KEYFOCUSABLE_H__ +#define __KEYFOCUSABLE_H__ + +#include "focusable.h" + +struct SDL_KeyboardEvent; + +class KeyFocusable : public Focusable +{ + + virtual void serial_cb(const SDL_Event*) override; + + virtual Uint32 stackID() const override; + +protected: + + virtual void key_cb(const SDL_KeyboardEvent*) = 0; + +public: + + using Focusable::Focusable; +}; + +#endif diff --git a/engine/include/types.h b/engine/include/types.h index 3141e6c..003c114 100644 --- a/engine/include/types.h +++ b/engine/include/types.h @@ -22,8 +22,11 @@ class FlatWindow; class FlatSpriter; class FlatMultiSpriter; +class task_s; + /* SDL types */ +typedef unsigned char Uint8; typedef unsigned int Uint32; struct SDL_Surface; diff --git a/engine/keyfocusable.cpp b/engine/keyfocusable.cpp new file mode 100644 index 0000000..39f4b01 --- /dev/null +++ b/engine/keyfocusable.cpp @@ -0,0 +1,14 @@ +#include "serial/keyfocusable.h" +#include "SDL2/SDL.h" + +void KeyFocusable::serial_cb(const SDL_Event *event) +{ + key_cb(&event->key); +} + +Uint32 KeyFocusable::stackID() const +{ + // Set SDL_KEYDOWN by default + return SDL_KEYDOWN; +} + @@ -0,0 +1,24 @@ +- Test one: open window for 100 frames * + +- FlatTasks * +- FlatSignals * +- FlatEvent (basic) * +- Bind keyboard on FlatWindow * +- Construct core channel * +- Bind notify closing window with signals * + +- Test two: open window and close with keyboard * + +- Exceptions +- Priorities on FlatTask +- FlatEvent (all) + +- Test three: manage multiple events and possible vulnerability + +- Fixes +- FlatLayer +- FlatSprite + +- Test four: animation test + +- Sound diff --git a/test/main.cpp b/test/main.cpp index c30e5f9..5a441a7 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -10,7 +10,7 @@ int main() FlatWindow win(600, 900, "Stocazzo"); flat_status status; - init_flatland(win, loop, status, 60); + init_flatland(&win, loop, status, 60); return 0; } @@ -23,7 +23,7 @@ void loop(float dt) { ++count; - if (count == 100) + if (count == 1000) quit_flatland(); cout << "Loop number: " << count << endl; Binary files differdiff --git a/test/test1.cpp b/test/test1.cpp new file mode 100644 index 0000000..4d7c71f --- /dev/null +++ b/test/test1.cpp @@ -0,0 +1,30 @@ +#include "flatland.h" +#include "flatwindow.h" + +int count = 0; + +void loop(float); + +int main() +{ + FlatWindow win(600, 900, "Stocazzo"); + flat_status status; + + init_flatland(&win, loop, status, 60); + + return 0; +} + +#include <iostream> + +using namespace std; + +void loop(float dt) +{ + ++count; + + if (count == 100) + quit_flatland(); + + cout << "Loop number: " << count << endl; +} |