From 006a76c099f502d10290e22dce3477b87efc4735 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 24 Mar 2017 16:26:43 +0000 Subject: [PATCH] Refactor registration of drawing engines --- src/openrct2-ui/UiContext.cpp | 8 +++ .../drawing/engines/DrawingEngines.h | 43 ++++++------ .../drawing/engines/SoftwareDrawingEngine.cpp | 24 +------ .../engines/opengl/OpenGLDrawingEngine.cpp | 12 +--- src/openrct2/Context.cpp | 6 ++ src/openrct2/Context.h | 10 ++- src/openrct2/core/Registration.hpp | 67 +++++++++++++++++++ src/openrct2/drawing/IDrawingEngine.h | 31 +++++---- src/openrct2/drawing/NewDrawing.cpp | 20 +++--- 9 files changed, 143 insertions(+), 78 deletions(-) create mode 100644 src/openrct2/core/Registration.hpp diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 007b10a286..6863b0a758 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -14,6 +14,10 @@ *****************************************************************************/ #pragma endregion +#include +#include +#include +#include #include "UiContext.h" #include "drawing\engines\DrawingEngines.h" @@ -24,6 +28,7 @@ class UiContext : public IUiContext { private: IContext * const _context; + std::vector> _registrations; // Drawing engines SoftwareDrawingEngineFactory _softwareDrawingFactory; @@ -36,6 +41,9 @@ public: UiContext(IContext * context) : _context(context) { + _registrations.emplace_back(context->RegisterDrawingEngine(DRAWING_ENGINE_SOFTWARE, &_softwareDrawingFactory)); + _registrations.emplace_back(context->RegisterDrawingEngine(DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY, &_hardwareDrawingFactory)); + _registrations.emplace_back(context->RegisterDrawingEngine(DRAWING_ENGINE_OPENGL, &_openglDrawingFactory)); } ~UiContext() override diff --git a/src/openrct2-ui/drawing/engines/DrawingEngines.h b/src/openrct2-ui/drawing/engines/DrawingEngines.h index f824c203d3..08a364425d 100644 --- a/src/openrct2-ui/drawing/engines/DrawingEngines.h +++ b/src/openrct2-ui/drawing/engines/DrawingEngines.h @@ -19,32 +19,27 @@ #include #include -interface IDrawingEngineFactory; - -class SoftwareDrawingEngineFactory : public IDrawingEngineFactory +namespace OpenRCT2 { namespace Ui { -public: - SoftwareDrawingEngineFactory(); - ~SoftwareDrawingEngineFactory() override; - IDrawingEngine * Create() override; -}; + class SoftwareDrawingEngineFactory : public Drawing::IDrawingEngineFactory + { + public: + IDrawingEngine * Create() override; + }; -class HardwareDisplayDrawingEngineFactory : public IDrawingEngineFactory -{ -public: - HardwareDisplayDrawingEngineFactory(); - ~HardwareDisplayDrawingEngineFactory() override; - IDrawingEngine * Create() override; -}; + class HardwareDisplayDrawingEngineFactory : public Drawing::IDrawingEngineFactory + { + public: + IDrawingEngine * Create() override; + }; -#ifndef DISABLE_OPENGL + #ifndef DISABLE_OPENGL -class OpenGLDrawingEngineFactory : public IDrawingEngineFactory -{ -public: - OpenGLDrawingEngineFactory(); - ~OpenGLDrawingEngineFactory() override; - IDrawingEngine * Create() override; -}; + class OpenGLDrawingEngineFactory : public Drawing::IDrawingEngineFactory + { + public: + IDrawingEngine * Create() override; + }; -#endif // DISABLE_OPENGL + #endif // DISABLE_OPENGL +} } diff --git a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp index d31ce3c916..e5da799b3a 100644 --- a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp @@ -828,32 +828,12 @@ private: } }; -SoftwareDrawingEngineFactory::SoftwareDrawingEngineFactory() -{ - DrawingEngineFactory::Register(DRAWING_ENGINE_SOFTWARE, this); -} - -SoftwareDrawingEngineFactory::~SoftwareDrawingEngineFactory() -{ - DrawingEngineFactory::Unregister(DRAWING_ENGINE_SOFTWARE); -} - -IDrawingEngine * SoftwareDrawingEngineFactory::Create() +IDrawingEngine * OpenRCT2::Ui::SoftwareDrawingEngineFactory::Create() { return new SoftwareDrawingEngine(false); } -HardwareDisplayDrawingEngineFactory::HardwareDisplayDrawingEngineFactory() -{ - DrawingEngineFactory::Register(DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY, this); -} - -HardwareDisplayDrawingEngineFactory::~HardwareDisplayDrawingEngineFactory() -{ - DrawingEngineFactory::Unregister(DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY); -} - -IDrawingEngine * HardwareDisplayDrawingEngineFactory::Create() +IDrawingEngine * OpenRCT2::Ui::HardwareDisplayDrawingEngineFactory::Create() { return new SoftwareDrawingEngine(true); } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 0d7d431902..185641bb21 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -499,17 +499,7 @@ private: } }; -OpenGLDrawingEngineFactory::OpenGLDrawingEngineFactory() -{ - DrawingEngineFactory::Register(DRAWING_ENGINE_OPENGL, this); -} - -OpenGLDrawingEngineFactory::~OpenGLDrawingEngineFactory() -{ - DrawingEngineFactory::Unregister(DRAWING_ENGINE_OPENGL); -} - -IDrawingEngine * OpenGLDrawingEngineFactory::Create() +IDrawingEngine * OpenRCT2::Ui::OpenGLDrawingEngineFactory::Create() { return new OpenGLDrawingEngine(); } diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index d8b66ec73d..3a5e02796e 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include "drawing/IDrawingEngine.h" #include "Context.h" #include "OpenRCT2.h" @@ -30,6 +31,11 @@ public: { } + IRegistration * RegisterDrawingEngine(sint32 type, Drawing::IDrawingEngineFactory * factory) override + { + return Drawing::DrawingEngineFactory::Register((DRAWING_ENGINE)type, factory); + } + sint32 RunOpenRCT2(int argc, char * * argv) override { return ::RunOpenRCT2(argc, argv); diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index 5557f153f8..05bca70078 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -20,12 +20,20 @@ namespace OpenRCT2 { + interface IRegistration; + + namespace Drawing + { + interface IDrawingEngineFactory; + } + /** * Represents an instance of OpenRCT2 and can be used to get various services. */ interface IContext { - virtual ~IContext() { } + virtual ~IContext() = default; + virtual IRegistration * RegisterDrawingEngine(sint32 type, Drawing::IDrawingEngineFactory * factory) abstract; virtual sint32 RunOpenRCT2(int argc, char * * argv) abstract; }; diff --git a/src/openrct2/core/Registration.hpp b/src/openrct2/core/Registration.hpp new file mode 100644 index 0000000000..de8ac29ea1 --- /dev/null +++ b/src/openrct2/core/Registration.hpp @@ -0,0 +1,67 @@ +#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers +/***************************************************************************** +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* OpenRCT2 is the work of many authors, a full list can be found in contributors.md +* For more information, visit https://github.com/OpenRCT2/OpenRCT2 +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* A full copy of the GNU General Public License can be found in licence.txt +*****************************************************************************/ +#pragma endregion + +#pragma once + +#include "../common.h" + +namespace OpenRCT2 +{ + /** + * Represents a registration of some service which when deleted will be + * unregistered. + */ + interface IRegistration + { + virtual ~IRegistration() = default; + }; + + class Registration + { + private: + /** + * Class which can wrap a function in an IRegistration. + */ + template + struct CallbackRegistration : public IRegistration + { + private: + T _callback; + + public: + CallbackRegistration(T callback) : + _callback(callback) + { + } + + virtual ~CallbackRegistration() override + { + _callback(); + } + }; + + public: + /** + * Creates a new IRegistration which when deleted, calls the given + * function. + */ + template + static IRegistration * Create(T unregisterCallback) + { + return new CallbackRegistration(unregisterCallback); + } + }; +} diff --git a/src/openrct2/drawing/IDrawingEngine.h b/src/openrct2/drawing/IDrawingEngine.h index 1c3a706f4b..574913cde7 100644 --- a/src/openrct2/drawing/IDrawingEngine.h +++ b/src/openrct2/drawing/IDrawingEngine.h @@ -67,18 +67,6 @@ interface IDrawingEngine virtual void InvalidateImage(uint32 image) abstract; }; -interface IDrawingEngineFactory -{ - virtual ~IDrawingEngineFactory() { } - virtual IDrawingEngine * Create() abstract; -}; - -namespace DrawingEngineFactory -{ - void Register(DRAWING_ENGINE type, IDrawingEngineFactory * factory); - void Unregister(DRAWING_ENGINE type); -} - interface IRainDrawer { virtual ~IRainDrawer() { } @@ -90,4 +78,23 @@ interface IRainDrawer sint32 yStart) abstract; }; +namespace OpenRCT2 +{ + interface IRegistration; + + namespace Drawing + { + interface IDrawingEngineFactory + { + virtual ~IDrawingEngineFactory() { } + virtual IDrawingEngine * Create() abstract; + }; + + namespace DrawingEngineFactory + { + IRegistration * Register(DRAWING_ENGINE type, IDrawingEngineFactory * factory); + } + } +} + #endif diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index 9f5360632c..0f29b4f016 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -15,6 +15,7 @@ #pragma endregion #include "../core/Exception.hpp" +#include "../core/Registration.hpp" #include "IDrawingContext.h" #include "IDrawingEngine.h" #include "NewDrawing.h" @@ -29,26 +30,29 @@ extern "C" #include "../rct2.h" } +using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; + static sint32 _drawingEngineType = DRAWING_ENGINE_SOFTWARE; static IDrawingEngine * _drawingEngine = nullptr; static IDrawingEngineFactory * _drawingEngineFactories[DRAWING_ENGINE_COUNT] = { nullptr }; -void DrawingEngineFactory::Register(DRAWING_ENGINE type, IDrawingEngineFactory * factory) +IRegistration * DrawingEngineFactory::Register(DRAWING_ENGINE type, IDrawingEngineFactory * factory) { if (_drawingEngineFactories[type] != nullptr) { throw std::invalid_argument("Engine already registered."); } _drawingEngineFactories[type] = factory; -} -void DrawingEngineFactory::Unregister(DRAWING_ENGINE type) -{ - if (_drawingEngineFactories[type] == nullptr) + return Registration::Create([type, factory]() -> void { - throw std::invalid_argument("Engine not registered."); - } - _drawingEngineFactories[type] = nullptr; + if (_drawingEngineFactories[type] != factory) + { + throw std::invalid_argument("Engine not registered."); + } + _drawingEngineFactories[type] = nullptr; + }); } extern "C"