Switch from MVC (Model-View-Controller) pattern to a modified MVP (Model-View-Presenter) pattern, to toss out the inconvenient Controller
This commit is contained in:
Irlan 2018-04-12 19:25:00 -03:00
parent 7bec2853b1
commit 9d271cc5ed
6 changed files with 140 additions and 100 deletions

View File

@ -26,7 +26,6 @@
#include <testbed/framework/model.h> #include <testbed/framework/model.h>
#include <testbed/framework/view.h> #include <testbed/framework/view.h>
#include <testbed/framework/controller.h>
// //
GLFWwindow* g_window; GLFWwindow* g_window;
@ -34,21 +33,20 @@ GLFWwindow* g_window;
// //
Model* g_model; Model* g_model;
View* g_view; View* g_view;
Controller* g_controller;
static void WindowSize(GLFWwindow* ww, int w, int h) static void WindowSize(GLFWwindow* ww, int w, int h)
{ {
g_controller->Event_SetWindowSize(u32(w), u32(h)); g_view->Event_SetWindowSize(w, h);
} }
static void CursorMove(GLFWwindow* w, double x, double y) static void CursorMove(GLFWwindow* w, double x, double y)
{ {
g_controller->Event_Move_Cursor(float32(x), float32(y)); g_view->Event_Move_Cursor(float(x), float(y));
} }
static void WheelScroll(GLFWwindow* w, double dx, double dy) static void WheelScroll(GLFWwindow* w, double dx, double dy)
{ {
g_controller->Event_Scroll(float32(dx), float32(dy)); g_view->Event_Scroll(float(dx), float(dy));
} }
static void MouseButton(GLFWwindow* w, int button, int action, int mods) static void MouseButton(GLFWwindow* w, int button, int action, int mods)
@ -57,12 +55,12 @@ static void MouseButton(GLFWwindow* w, int button, int action, int mods)
{ {
case GLFW_PRESS: case GLFW_PRESS:
{ {
g_controller->Event_Press_Mouse(button); g_view->Event_Press_Mouse(button);
break; break;
} }
case GLFW_RELEASE: case GLFW_RELEASE:
{ {
g_controller->Event_Release_Mouse(button); g_view->Event_Release_Mouse(button);
break; break;
} }
default: default:
@ -78,13 +76,12 @@ static void KeyButton(GLFWwindow* w, int button, int scancode, int action, int m
{ {
case GLFW_PRESS: case GLFW_PRESS:
{ {
g_controller->Event_Press_Key(button); g_view->Event_Press_Key(button);
break; break;
} }
case GLFW_RELEASE: case GLFW_RELEASE:
{ {
g_controller->Event_Release_Key(button); g_view->Event_Release_Key(button);
break; break;
} }
default: default:
@ -98,7 +95,7 @@ static void Run()
{ {
int w, h; int w, h;
glfwGetWindowSize(g_window, &w, &h); glfwGetWindowSize(g_window, &w, &h);
g_controller->Event_SetWindowSize(u32(w), u32(h)); g_view->Event_SetWindowSize(u32(w), u32(h));
while (glfwWindowShouldClose(g_window) == 0) while (glfwWindowShouldClose(g_window) == 0)
{ {
@ -187,15 +184,11 @@ int main(int argc, char** args)
// //
g_model = new Model(); g_model = new Model();
g_view = new View(g_window, g_model); g_view = new View(g_window, g_model);
g_controller = new Controller(g_model, g_view);
// Run // Run
Run(); Run();
// //
delete g_controller;
g_controller = nullptr;
delete g_view; delete g_view;
g_view = nullptr; g_view = nullptr;

View File

@ -16,13 +16,10 @@
* 3. This notice may not be removed or altered from any source distribution. * 3. This notice may not be removed or altered from any source distribution.
*/ */
#include <testbed/framework/controller.h> #include <testbed/framework/presenter.h>
#include <testbed/framework/model.h> #include <testbed/framework/model.h>
#include <testbed/framework/view.h> #include <testbed/framework/view.h>
// !
#include <glfw/glfw3.h>
// ! // !
static inline b3Vec2 GetCursorPosition() static inline b3Vec2 GetCursorPosition()
{ {
@ -34,35 +31,25 @@ static inline b3Vec2 GetCursorPosition()
return b3Vec2(float32(x), float32(y)); return b3Vec2(float32(x), float32(y));
} }
Controller::Controller(Model* model, View* view) Presenter::Presenter(Model* model, View* view)
{ {
m_model = model; m_model = model;
m_view = view; m_view = view;
m_leftDown = false;
m_rightDown = false;
m_shiftDown = false;
m_ps0.SetZero();
} }
Controller::~Controller() Presenter::~Presenter()
{ {
} }
void Controller::Event_SetWindowSize(u32 w, u32 h) void Presenter::Event_SetWindowSize(float w, float h)
{ {
m_model->Command_ResizeCamera(float32(w), float32(h)); m_model->Command_ResizeCamera(w, h);
} }
void Controller::Event_Press_Key(int button) void Presenter::Event_Press_Key(int button)
{ {
if (button == GLFW_KEY_LEFT_SHIFT) if (m_view->m_shiftDown)
{
m_shiftDown = true;
}
if (m_shiftDown)
{ {
if (button == GLFW_KEY_DOWN) if (button == GLFW_KEY_DOWN)
{ {
@ -80,82 +67,58 @@ void Controller::Event_Press_Key(int button)
} }
} }
void Controller::Event_Release_Key(int button) void Presenter::Event_Release_Key(int button)
{ {
if (button == GLFW_KEY_LEFT_SHIFT) if (!m_view->m_shiftDown)
{
m_shiftDown = false;
}
if (m_shiftDown)
{
}
else
{ {
m_model->Command_Release_Key(button); m_model->Command_Release_Key(button);
} }
} }
void Controller::Event_Press_Mouse(int button) void Presenter::Event_Press_Mouse(int button)
{ {
if (button == GLFW_MOUSE_BUTTON_LEFT) if (button == GLFW_MOUSE_BUTTON_LEFT)
{ {
m_leftDown = true; if (!m_view->m_shiftDown)
if (!m_shiftDown)
{ {
m_model->Command_Press_Mouse_Left(GetCursorPosition()); m_model->Command_Press_Mouse_Left(GetCursorPosition());
} }
} }
if (button == GLFW_MOUSE_BUTTON_RIGHT)
{
m_rightDown = true;
}
} }
void Controller::Event_Release_Mouse(int button) void Presenter::Event_Release_Mouse(int button)
{ {
if (button == GLFW_MOUSE_BUTTON_LEFT) if (button == GLFW_MOUSE_BUTTON_LEFT)
{ {
m_leftDown = false; if (!m_view->m_shiftDown)
if (!m_shiftDown)
{ {
m_model->Command_Release_Mouse_Left(GetCursorPosition()); m_model->Command_Release_Mouse_Left(GetCursorPosition());
} }
} }
if (button == GLFW_MOUSE_BUTTON_RIGHT)
{
m_rightDown = false;
}
} }
void Controller::Event_Move_Cursor(float32 x, float32 y) void Presenter::Event_Move_Cursor(float x, float y)
{ {
b3Vec2 ps; b3Vec2 ps;
ps.Set(float32(x), float32(y)); ps.Set(x, y);
b3Vec2 dp = ps - m_ps0; b3Vec2 dp = ps - m_view->m_ps0;
m_ps0 = ps;
float32 ndx = b3Clamp(dp.x, -1.0f, 1.0f); float32 ndx = b3Clamp(dp.x, -1.0f, 1.0f);
float32 ndy = b3Clamp(dp.y, -1.0f, 1.0f); float32 ndy = b3Clamp(dp.y, -1.0f, 1.0f);
if (m_shiftDown) if (m_view->m_shiftDown)
{ {
if (m_leftDown) if (m_view->m_leftDown)
{ {
float32 ax = -0.005f * B3_PI * ndx; float32 ax = -0.005f * B3_PI * ndx;
float32 ay = -0.005f * B3_PI * ndy; float32 ay = -0.005f * B3_PI * ndy;
m_model->Command_RotateCameraY(ax); m_model->Command_RotateCameraY(ax);
m_model->Command_RotateCameraX(ay); m_model->Command_RotateCameraX(ay);
} }
if (m_rightDown) if (m_view->m_rightDown)
{ {
float32 tx = 0.2f * ndx; float32 tx = 0.2f * ndx;
float32 ty = -0.2f * ndy; float32 ty = -0.2f * ndy;
@ -170,11 +133,11 @@ void Controller::Event_Move_Cursor(float32 x, float32 y)
} }
} }
void Controller::Event_Scroll(float32 dx, float32 dy) void Presenter::Event_Scroll(float dx, float dy)
{ {
if (m_shiftDown) if (m_view->m_shiftDown)
{ {
float32 ny = b3Clamp(dy, -1.0f, 1.0f); float32 ny = b3Clamp(dy, -1.0f, 1.0f);
m_model->Command_ZoomCamera(1.0f * ny); m_model->Command_ZoomCamera(1.0f * ny);
} }
} }

View File

@ -16,44 +16,34 @@
* 3. This notice may not be removed or altered from any source distribution. * 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef CONTROLLER_H #ifndef PRESENTER_H
#define CONTROLLER_H #define PRESENTER_H
#include <bounce/common/math/vec2.h> #include <bounce/common/math/vec2.h>
class Model; class Model;
class View; class View;
class Controller class Presenter
{ {
public: public:
Controller(Model* model, View* view); Presenter(Model* model, View* view);
~Controller(); ~Presenter();
void Event_SetWindowSize(u32 w, u32 h); void Event_SetWindowSize(float w, float h);
void Event_Press_Key(int button); void Event_Press_Key(int button);
void Event_Release_Key(int button); void Event_Release_Key(int button);
void Event_Press_Mouse(int button); void Event_Press_Mouse(int button);
void Event_Release_Mouse(int button); void Event_Release_Mouse(int button);
void Event_Move_Cursor(float x, float y);
void Event_Move_Cursor(float32 x, float32 y); void Event_Scroll(float dx, float dy);
void Event_Scroll(float32 dx, float32 dy);
private: private:
friend class Model; friend class Model;
friend class View; friend class View;
Model* m_model; Model* m_model;
View* m_view; View* m_view;
bool m_leftDown;
bool m_rightDown;
bool m_shiftDown;
b3Vec2 m_ps0;
// Ray3 m_ray0;
}; };
#endif #endif

View File

@ -26,6 +26,8 @@
#else #else
#endif #endif
#include <glfw/glfw3.h>
static bool GetTestName(void* userData, int idx, const char** name) static bool GetTestName(void* userData, int idx, const char** name)
{ {
assert(u32(idx) < g_testCount); assert(u32(idx) < g_testCount);
@ -109,7 +111,7 @@ static inline void ImGui_GLFW_GL_RenderDrawData(ImDrawData* draw_data)
} }
View::View(GLFWwindow* window, Model* model) View::View(GLFWwindow* window, Model* model) : m_presenter(model, this)
{ {
m_window = window; m_window = window;
m_model = model; m_model = model;
@ -125,6 +127,11 @@ View::View(GLFWwindow* window, Model* model)
ImGui_GLFW_GL_Init(m_window, false); ImGui_GLFW_GL_Init(m_window, false);
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
m_leftDown = false;
m_rightDown = false;
m_shiftDown = false;
m_ps0.SetZero();
} }
View::~View() View::~View()
@ -135,6 +142,75 @@ View::~View()
ImGui::DestroyContext(); ImGui::DestroyContext();
} }
void View::Event_SetWindowSize(int w, int h)
{
m_presenter.Event_SetWindowSize(float32(w), float32(h));
}
void View::Event_Press_Key(int button)
{
if (button == GLFW_KEY_LEFT_SHIFT)
{
m_shiftDown = true;
}
m_presenter.Event_Press_Key(button);
}
void View::Event_Release_Key(int button)
{
if (button == GLFW_KEY_LEFT_SHIFT)
{
m_shiftDown = false;
}
m_presenter.Event_Release_Key(button);
}
void View::Event_Press_Mouse(int button)
{
if (button == GLFW_MOUSE_BUTTON_LEFT)
{
m_leftDown = true;
}
if (button == GLFW_MOUSE_BUTTON_RIGHT)
{
m_rightDown = true;
}
m_presenter.Event_Press_Mouse(button);
}
void View::Event_Release_Mouse(int button)
{
if (button == GLFW_MOUSE_BUTTON_LEFT)
{
m_leftDown = false;
}
if (button == GLFW_MOUSE_BUTTON_RIGHT)
{
m_rightDown = false;
}
m_presenter.Event_Release_Mouse(button);
}
void View::Event_Move_Cursor(float x, float y)
{
b3Vec2 ps(x, y);
m_presenter.Event_Move_Cursor(ps.x, ps.y);
m_ps0 = ps;
}
void View::Event_Scroll(float dx, float dy)
{
m_presenter.Event_Scroll(dx, dy);
}
void View::Command_PreDraw() void View::Command_PreDraw()
{ {
ImGui_GLFW_GL_NewFrame(); ImGui_GLFW_GL_NewFrame();

View File

@ -19,25 +19,43 @@
#ifndef VIEW_H #ifndef VIEW_H
#define VIEW_H #define VIEW_H
#include <bounce/common/math/vec2.h>
#include <testbed/framework/presenter.h>
struct GLFWwindow; struct GLFWwindow;
class Model; class Model;
class View class View
{ {
public: public:
View(GLFWwindow* window, Model* model); View(GLFWwindow* window, Model* model);
~View(); ~View();
void Event_SetWindowSize(int w, int h);
void Event_Press_Key(int button);
void Event_Release_Key(int button);
void Event_Press_Mouse(int button);
void Event_Release_Mouse(int button);
void Event_Move_Cursor(float x, float y);
void Event_Scroll(float dx, float dy);
void Command_PreDraw(); void Command_PreDraw();
void Command_Draw(); void Command_Draw();
void Command_PostDraw(); void Command_PostDraw();
private: private:
GLFWwindow * m_window; friend class Presenter;
Presenter m_presenter;
Model* m_model; Model* m_model;
GLFWwindow* m_window;
bool m_leftDown;
bool m_rightDown;
bool m_shiftDown;
b3Vec2 m_ps0;
// Ray3 m_ray0;
}; };
#endif #endif

View File

@ -269,7 +269,7 @@ solution (solution_name)
examples_inc_dir .. "/testbed/framework/model.h", examples_inc_dir .. "/testbed/framework/model.h",
examples_inc_dir .. "/testbed/framework/view.h", examples_inc_dir .. "/testbed/framework/view.h",
examples_inc_dir .. "/testbed/framework/controller.h", examples_inc_dir .. "/testbed/framework/presenter.h",
examples_src_dir .. "/testbed/framework/test.h", examples_src_dir .. "/testbed/framework/test.h",
@ -282,7 +282,7 @@ solution (solution_name)
examples_inc_dir .. "/testbed/framework/model.cpp", examples_inc_dir .. "/testbed/framework/model.cpp",
examples_inc_dir .. "/testbed/framework/view.cpp", examples_inc_dir .. "/testbed/framework/view.cpp",
examples_inc_dir .. "/testbed/framework/controller.cpp", examples_inc_dir .. "/testbed/framework/presenter.cpp",
examples_src_dir .. "/testbed/framework/test.cpp", examples_src_dir .. "/testbed/framework/test.cpp",
examples_src_dir .. "/testbed/framework/test_entries.cpp", examples_src_dir .. "/testbed/framework/test_entries.cpp",