From eb35aedeeffd8677705390e51379351ad00ad99d Mon Sep 17 00:00:00 2001 From: Frank DeMarco Date: Fri, 3 May 2019 02:09:48 -0400 Subject: [PATCH] event dispatch --- demo/Demo.cpp | 194 +++++++++++++++++++++++------------------------ demo/Demo.hpp | 1 + demo/Makefile | 10 +-- src/Delegate.cpp | 33 ++++++++ src/Delegate.hpp | 28 +++++++ src/Game.cpp | 14 +++- src/Game.hpp | 5 +- src/Input.cpp | 11 +++ src/Input.hpp | 18 +++++ src/Location.hpp | 2 + src/Node.cpp | 5 ++ src/Node.hpp | 5 ++ 12 files changed, 218 insertions(+), 108 deletions(-) create mode 100644 src/Delegate.cpp create mode 100644 src/Delegate.hpp create mode 100644 src/Input.cpp create mode 100644 src/Input.hpp diff --git a/demo/Demo.cpp b/demo/Demo.cpp index 6d7e753..9a35b4d 100644 --- a/demo/Demo.cpp +++ b/demo/Demo.cpp @@ -343,103 +343,103 @@ struct Demo : Game void update() { - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) - { - flag_to_end(); - } - else if (event.type == SDL_KEYDOWN) - { - if (event.key.keysym.sym == SDLK_F9) - { - capture_screen(window); - } - else if (event.key.keysym.sym == SDLK_F10) - { - if (not is_recording) - { - start_recording(&is_recording); - } - else - { - end_recording(frames, &is_recording); - } - } - else if (event.key.keysym.sym == SDLK_F11) - { - if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) - { - SDL_SetWindowFullscreen(window, 0); - } - else - { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); - } - } - else if (SDL_GetModState() & KMOD_CTRL) - { - if (event.key.keysym.sym == SDLK_f) - { - show_framerate = not show_framerate; - } - else if (event.key.keysym.sym == SDLK_UP) - { - set_framerate(framerate + 1); - } - else if (event.key.keysym.sym == SDLK_DOWN) - { - set_framerate(framerate - 1); - } - } - else if (event.key.keysym.sym == SDLK_UP) - { - up_active = true; - } - else if (event.key.keysym.sym == SDLK_RIGHT) - { - right_active = true; - } - else if (event.key.keysym.sym == SDLK_DOWN) - { - down_active = true; - } - else if (event.key.keysym.sym == SDLK_LEFT) - { - left_active = true; - } - else if (event.key.keysym.sym == SDLK_SPACE) - { - if (is_gl_context) - { - load_sdl_context(); - } - else - { - load_gl_context(); - } - } - } - else if (event.type == SDL_KEYUP) - { - if (event.key.keysym.sym == SDLK_UP) - { - up_active = false; - } - else if (event.key.keysym.sym == SDLK_RIGHT) - { - right_active = false; - } - else if (event.key.keysym.sym == SDLK_DOWN) - { - down_active = false; - } - else if (event.key.keysym.sym == SDLK_LEFT) - { - left_active = false; - } - } - } + // while (SDL_PollEvent(&event)) + // { + // if (event.type == SDL_QUIT) + // { + // flag_to_end(); + // } + // else if (event.type == SDL_KEYDOWN) + // { + // if (event.key.keysym.sym == SDLK_F9) + // { + // capture_screen(window); + // } + // else if (event.key.keysym.sym == SDLK_F10) + // { + // if (not is_recording) + // { + // start_recording(&is_recording); + // } + // else + // { + // end_recording(frames, &is_recording); + // } + // } + // else if (event.key.keysym.sym == SDLK_F11) + // { + // if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) + // { + // SDL_SetWindowFullscreen(window, 0); + // } + // else + // { + // SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); + // } + // } + // else if (SDL_GetModState() & KMOD_CTRL) + // { + // if (event.key.keysym.sym == SDLK_f) + // { + // show_framerate = not show_framerate; + // } + // else if (event.key.keysym.sym == SDLK_UP) + // { + // set_framerate(framerate + 1); + // } + // else if (event.key.keysym.sym == SDLK_DOWN) + // { + // set_framerate(framerate - 1); + // } + // } + // else if (event.key.keysym.sym == SDLK_UP) + // { + // up_active = true; + // } + // else if (event.key.keysym.sym == SDLK_RIGHT) + // { + // right_active = true; + // } + // else if (event.key.keysym.sym == SDLK_DOWN) + // { + // down_active = true; + // } + // else if (event.key.keysym.sym == SDLK_LEFT) + // { + // left_active = true; + // } + // else if (event.key.keysym.sym == SDLK_SPACE) + // { + // if (is_gl_context) + // { + // load_sdl_context(); + // } + // else + // { + // load_gl_context(); + // } + // } + // } + // else if (event.type == SDL_KEYUP) + // { + // if (event.key.keysym.sym == SDLK_UP) + // { + // up_active = false; + // } + // else if (event.key.keysym.sym == SDLK_RIGHT) + // { + // right_active = false; + // } + // else if (event.key.keysym.sym == SDLK_DOWN) + // { + // down_active = false; + // } + // else if (event.key.keysym.sym == SDLK_LEFT) + // { + // left_active = false; + // } + // } + // } if (is_recording and ticks - last_capture_timestamp + capture_time_overflow > recording_capture_framerate) { diff --git a/demo/Demo.hpp b/demo/Demo.hpp index e84c587..4b5d5a1 100644 --- a/demo/Demo.hpp +++ b/demo/Demo.hpp @@ -34,6 +34,7 @@ #include "Location.hpp" #include "Sprite.hpp" #include "Input.hpp" +#include "Delegate.hpp" struct Mushroom : Sprite { diff --git a/demo/Makefile b/demo/Makefile index b4d2101..49e2915 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -36,18 +36,16 @@ $(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(CC_LINUX) $(CFLAGS) $< -o $@ -$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Node.hpp Game.hpp Location.hpp) -$(SFW_SRC_DIR)Game.o: $(addprefix $(SFW_SRC_DIR),Node.hpp Sprite.hpp Configuration.hpp) +$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.hpp Location.hpp) +$(SFW_SRC_DIR)Game.o: $(addprefix $(SFW_SRC_DIR),Sprite.hpp Configuration.hpp Delegate.hpp) $(SFW_SRC_DIR)Node.o: $(addprefix $(SFW_SRC_DIR),Game.hpp Configuration.hpp) -$(SFW_SRC_DIR)Configuration.o: $(SFW_SRC_DIR)Node.hpp -$(SFW_SRC_DIR)Input.o: $(SFW_SRC_DIR)Node.hpp -$(SFW_SRC_DIR)%.o: $(addprefix $(SFW_SRC_DIR),%.cpp %.hpp) +$(SFW_SRC_DIR)%.o: $(addprefix $(SFW_SRC_DIR),%.cpp %.hpp Node.cpp) $(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@ Demo.o: Demo.cpp Demo.hpp $(addprefix $(SFW_SRC_DIR),Sprite.hpp Node.hpp Game.hpp Location.hpp Input.hpp) $(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@ -linux: Demo.o $(addprefix $(SFW_SRC_DIR),Sprite.o Node.o Game.o Location.o Configuration.o Input.o) \ +linux: Demo.o $(addprefix $(SFW_SRC_DIR),Sprite.o Node.o Game.o Location.o Configuration.o Input.o Delegate.o) \ $(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) $(CPPC_LINUX) $(LFLAGS) -D__LINUX__ $^ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs -o demo diff --git a/src/Delegate.cpp b/src/Delegate.cpp new file mode 100644 index 0000000..0045587 --- /dev/null +++ b/src/Delegate.cpp @@ -0,0 +1,33 @@ +#include "Delegate.hpp" + +Delegate::Delegate(Node *parent) : Node(parent) {} + +void Delegate::add_subscriber(Node *instance, void (Node::*callback)(SDL_Event*), SDL_EventType type) +{ + if (subscribers.count(type) == 0) + { + subscribers[type] = {}; + } + Subscriber s = {instance, callback}; + subscribers[type].push_back(s); +} + +void Delegate::dispatch() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { + for (auto iter = subscribers.begin(); iter != subscribers.end(); iter++) + { + if (event.type == iter->first) + { + for (Subscriber subscriber : iter->second) + { + Node *n = subscriber.instance; + void (Node::*callback)(SDL_Event*) = subscriber.callback; + (n->*callback)(&event); + } + } + } + } +} diff --git a/src/Delegate.hpp b/src/Delegate.hpp new file mode 100644 index 0000000..27c604f --- /dev/null +++ b/src/Delegate.hpp @@ -0,0 +1,28 @@ +#ifndef Delegate_h_ +#define Delegate_h_ + +#include +#include + +#include "Node.hpp" + +#include "SDL.h" + +struct Subscriber +{ + Node *instance; + void (Node::*callback)(SDL_Event*); +}; + +struct Delegate : Node +{ + + std::map> subscribers; + + Delegate(Node*); + void add_subscriber(Node*, void (Node::*)(SDL_Event*), SDL_EventType); + void dispatch(); + +}; + +#endif diff --git a/src/Game.cpp b/src/Game.cpp index 6cc13f6..b82d3bf 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -2,6 +2,7 @@ Game::Game() { + delegate->add_subscriber(this, &Node::respond, SDL_QUIT); std::cout << "GLEW " << glewGetString(GLEW_VERSION) << std::endl; putenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN=0"); putenv("SDL_VIDEO_CENTERED=1"); @@ -129,16 +130,13 @@ void Game::run() last_frame_length = ticks - last_frame_timestamp; frame_time_overflow = last_frame_length + frame_time_overflow - frame_length; last_frame_timestamp = ticks; + delegate->dispatch(); update(); } SDL_Delay(15); } } -// void Game::update() -// { -// } - void Game::flag_to_end() { done = true; @@ -154,6 +152,14 @@ void Game::set_framerate(int fps) frame_length = 1000.0 / framerate; } +void Game::respond(SDL_Event *event) +{ + if (event->type == SDL_QUIT) + { + flag_to_end(); + } +} + void Game::quit() { if (glcontext != NULL) diff --git a/src/Game.hpp b/src/Game.hpp index 0626906..22a2448 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -17,6 +17,7 @@ #include "Node.hpp" #include "Configuration.hpp" +#include "Delegate.hpp" struct Game : Node { @@ -35,6 +36,7 @@ struct Game : Node float frame_length = 1000.0 / framerate; bool done = false, show_framerate = false, is_gl_context = true; Configuration *configuration = new Configuration(this); + Delegate *delegate = new Delegate(this); Game(); void print_error(std::string); @@ -44,8 +46,9 @@ struct Game : Node void load_gl_context(); void run(); void flag_to_end(); - virtual void update() = 0; + virtual void update() {}; void set_framerate(int); + void respond(SDL_Event*); void quit(); std::string get_class_name() { return "Game"; } diff --git a/src/Input.cpp b/src/Input.cpp new file mode 100644 index 0000000..0b06095 --- /dev/null +++ b/src/Input.cpp @@ -0,0 +1,11 @@ +#include "Input.hpp" + +Input::Input(Node *parent) : Node(parent) +{ + get_delegate()->add_subscriber(this, &Node::respond, SDL_KEYDOWN); +} + +void Input::respond(SDL_Event *event) +{ + std::cout << event->key.keysym.sym << std::endl; +} diff --git a/src/Input.hpp b/src/Input.hpp new file mode 100644 index 0000000..2d20416 --- /dev/null +++ b/src/Input.hpp @@ -0,0 +1,18 @@ +#ifndef Input_h_ +#define Input_h_ + +#include "SDL.h" + +#include "Node.hpp" +#include "Delegate.hpp" + +struct Input : Node +{ + + Input(Node*); + void respond(SDL_Event*); + std::string get_class_name() { return "Input"; } + +}; + +#endif diff --git a/src/Location.hpp b/src/Location.hpp index 7a29e1a..a28e465 100644 --- a/src/Location.hpp +++ b/src/Location.hpp @@ -1,6 +1,8 @@ #ifndef Location_h_ #define Location_h_ +#include + #include #define GLM_ENABLE_EXPERIMENTAL diff --git a/src/Node.cpp b/src/Node.cpp index 1199ec3..bdba8e6 100644 --- a/src/Node.cpp +++ b/src/Node.cpp @@ -14,6 +14,11 @@ Configuration* Node::get_configuration() return get_root()->configuration; } +Delegate* Node::get_delegate() +{ + return get_root()->delegate; +} + Game* Node::get_root() { Node *current = this; diff --git a/src/Node.hpp b/src/Node.hpp index 76337bf..cdb1194 100644 --- a/src/Node.hpp +++ b/src/Node.hpp @@ -3,10 +3,13 @@ #include +#include "SDL.h" + #include "filesystem.hpp" struct Game; struct Configuration; +struct Delegate; struct Node { @@ -17,7 +20,9 @@ struct Node Node(Node*); Game *get_root(); Configuration* get_configuration(); + Delegate* get_delegate(); void print_branch(); + virtual void respond(SDL_Event*) {}; virtual std::string get_class_name() { return "Node"; }; };