瀏覽代碼

Properly cleanup global libRocket system on Core::Shutdown. This allows libRocket to be Shutdown and reinitialised within the same execution.

Added different classes of events to the plugin system. This means not all plugins need to receive document and element events - slight performance gains.
Lloyd Weehuizen 15 年之前
父節點
當前提交
0e8316e5b4

+ 14 - 2
Include/Rocket/Core/Plugin.h

@@ -48,8 +48,20 @@ class ROCKETCORE_API Plugin
 public:
 public:
 	virtual ~Plugin();
 	virtual ~Plugin();
 
 
-	/// Called when Rocket is initialised, or immediately when the plugin registers itself if Rocket has already been
-	/// initialised.
+	enum EventClasses
+	{
+		EVT_BASIC		= (1 << 0),		// Initialise, Shutdown, ContextCreate, ContextDestroy
+		EVT_DOCUMENT	= (1 << 1),		// DocumentOpen, DocumentLoad, DocumentUnload
+		EVT_ELEMENT		= (1 << 2),		// ElementCreate, ElementDestroy
+
+		EVT_ALL			= EVT_BASIC | EVT_DOCUMENT | EVT_ELEMENT
+	};
+	/// Called when the plugin is registered to determine
+	/// which of the above event types the plugin is interested in
+	virtual int GetEventClasses();
+
+	/// Called when Rocket is initialised, or immediately when the plugin registers itself if 
+	/// Rocket has already been initialised.
 	virtual void OnInitialise();
 	virtual void OnInitialise();
 	/// Called when Rocket shuts down.
 	/// Called when Rocket shuts down.
 	virtual void OnShutdown();
 	virtual void OnShutdown();

+ 22 - 2
Source/Controls/Controls.cpp

@@ -30,6 +30,8 @@
 #include <Rocket/Core/Factory.h>
 #include <Rocket/Core/Factory.h>
 #include <Rocket/Core/StyleSheetSpecification.h>
 #include <Rocket/Core/StyleSheetSpecification.h>
 #include <Rocket/Core/XMLParser.h>
 #include <Rocket/Core/XMLParser.h>
+#include <Rocket/Core/Plugin.h>
+#include <Rocket/Core/Core.h>
 #include "ElementTextSelection.h"
 #include "ElementTextSelection.h"
 #include "XMLNodeHandlerDataGrid.h"
 #include "XMLNodeHandlerDataGrid.h"
 #include "XMLNodeHandlerTabSet.h"
 #include "XMLNodeHandlerTabSet.h"
@@ -102,10 +104,25 @@ void RegisterXMLNodeHandlers()
 	node_handler->RemoveReference();
 	node_handler->RemoveReference();
 }
 }
 
 
-void Initialise()
+static bool initialised = false;
+
+class ControlsPlugin : public Rocket::Core::Plugin
 {
 {
-	static bool initialised = false;
+public:
+	void OnShutdown()
+	{
+		initialised = false;
+		delete this;
+	}
+
+	int GetEventClasses()
+	{
+		return Rocket::Core::Plugin::EVT_BASIC;
+	}
+};
 
 
+void Initialise()
+{
 	// Prevent double initialisation
 	// Prevent double initialisation
 	if (!initialised)
 	if (!initialised)
 	{
 	{
@@ -117,6 +134,9 @@ void Initialise()
 		// Register the XML node handlers for our elements that require special parsing.
 		// Register the XML node handlers for our elements that require special parsing.
 		RegisterXMLNodeHandlers();
 		RegisterXMLNodeHandlers();
 
 
+		// Register the controls plugin, so we'll be notified on Shutdown
+		Rocket::Core::RegisterPlugin(new ControlsPlugin());
+
 		initialised = true;
 		initialised = true;
 	}
 	}
 }
 }

+ 4 - 7
Source/Core/Core.cpp

@@ -34,13 +34,6 @@
 #include "StyleSheetFactory.h"
 #include "StyleSheetFactory.h"
 #include "TemplateCache.h"
 #include "TemplateCache.h"
 #include "TextureDatabase.h"
 #include "TextureDatabase.h"
-/*#if defined ROCKET_PLATFORM_WIN32
-#include <windows.h>
-#elif defined ROCKET_PLATFORM_MACOSX
-#include <Carbon/Carbon.h>
-#elif defined ROCKET_PLATFORM_LINUX
-#include <unistd.h>
-#endif*/
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
@@ -146,6 +139,10 @@ void Shutdown()
 
 
 	if (system_interface != NULL)
 	if (system_interface != NULL)
 		system_interface->RemoveReference();
 		system_interface->RemoveReference();
+	
+	render_interface = NULL;
+	file_interface = NULL;
+	system_interface = NULL;
 		
 		
 	StringStorage::ClearPools();
 	StringStorage::ClearPools();
 }
 }

+ 6 - 0
Source/Core/Factory.cpp

@@ -128,21 +128,27 @@ void Factory::Shutdown()
 {
 {
 	for (ElementInstancerMap::iterator i = element_instancers.begin(); i != element_instancers.end(); ++i)
 	for (ElementInstancerMap::iterator i = element_instancers.begin(); i != element_instancers.end(); ++i)
 		(*i).second->RemoveReference();
 		(*i).second->RemoveReference();
+	element_instancers.clear();
 
 
 	for (DecoratorInstancerMap::iterator i = decorator_instancers.begin(); i != decorator_instancers.end(); ++i)
 	for (DecoratorInstancerMap::iterator i = decorator_instancers.begin(); i != decorator_instancers.end(); ++i)
 		(*i).second->RemoveReference();
 		(*i).second->RemoveReference();
+	decorator_instancers.clear();
 
 
 	for (FontEffectInstancerMap::iterator i = font_effect_instancers.begin(); i != font_effect_instancers.end(); ++i)
 	for (FontEffectInstancerMap::iterator i = font_effect_instancers.begin(); i != font_effect_instancers.end(); ++i)
 		(*i).second->RemoveReference();
 		(*i).second->RemoveReference();
+	font_effect_instancers.clear();
 
 
 	if (context_instancer)
 	if (context_instancer)
 		context_instancer->RemoveReference();
 		context_instancer->RemoveReference();
+	context_instancer = NULL;
 
 
 	if (event_listener_instancer)
 	if (event_listener_instancer)
 		event_listener_instancer->RemoveReference();
 		event_listener_instancer->RemoveReference();
+	event_listener_instancer = NULL;
 
 
 	if (event_instancer)
 	if (event_instancer)
 		event_instancer->RemoveReference();
 		event_instancer->RemoveReference();
+	event_instancer = NULL;
 
 
 	XMLParser::ReleaseHandlers();
 	XMLParser::ReleaseHandlers();
 }
 }

+ 5 - 0
Source/Core/Plugin.cpp

@@ -35,6 +35,11 @@ Plugin::~Plugin()
 {
 {
 }
 }
 
 
+int Plugin::GetEventClasses()
+{
+	return EVT_ALL;
+}
+
 void Plugin::OnInitialise()
 void Plugin::OnInitialise()
 {
 {
 }
 }

+ 32 - 25
Source/Core/PluginRegistry.cpp

@@ -33,85 +33,92 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 
 
 typedef std::vector< Plugin* > PluginList;
 typedef std::vector< Plugin* > PluginList;
-PluginList plugins;
+static PluginList basic_plugins;
+static PluginList document_plugins;
+static PluginList element_plugins;
 
 
 PluginRegistry::PluginRegistry()
 PluginRegistry::PluginRegistry()
 {
 {
 }
 }
 
 
-PluginRegistry::~PluginRegistry()
-{
-}
-
 void PluginRegistry::RegisterPlugin(Plugin* plugin)
 void PluginRegistry::RegisterPlugin(Plugin* plugin)
 {
 {
-	plugins.push_back(plugin);
+	int event_classes = plugin->GetEventClasses();
+	
+	if (event_classes & Plugin::EVT_BASIC)
+		basic_plugins.push_back(plugin);
+	if (event_classes & Plugin::EVT_DOCUMENT)
+		document_plugins.push_back(plugin);
+	if (event_classes & Plugin::EVT_ELEMENT)
+		element_plugins.push_back(plugin);
 }
 }
 
 
 // Calls OnInitialise() on all plugins.
 // Calls OnInitialise() on all plugins.
 void PluginRegistry::NotifyInitialise()
 void PluginRegistry::NotifyInitialise()
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnInitialise();
+	for (size_t i = 0; i < basic_plugins.size(); ++i)
+		basic_plugins[i]->OnInitialise();
 }
 }
 
 
 // Calls OnShutdown() on all plugins.
 // Calls OnShutdown() on all plugins.
 void PluginRegistry::NotifyShutdown()
 void PluginRegistry::NotifyShutdown()
 {
 {
-	while (!plugins.empty())
+	while (!basic_plugins.empty())
 	{
 	{
-		plugins.back()->OnShutdown();
-		plugins.pop_back();
+		basic_plugins.back()->OnShutdown();
+		basic_plugins.pop_back();
 	}
 	}
+	document_plugins.clear();
+	element_plugins.clear();
 }
 }
 
 
 // Calls OnContextCreate() on all plugins.
 // Calls OnContextCreate() on all plugins.
 void PluginRegistry::NotifyContextCreate(Context* context)
 void PluginRegistry::NotifyContextCreate(Context* context)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnContextCreate(context);
+	for (size_t i = 0; i < basic_plugins.size(); ++i)
+		basic_plugins[i]->OnContextCreate(context);
 }
 }
 
 
 // Calls OnContextDestroy() on all plugins.
 // Calls OnContextDestroy() on all plugins.
 void PluginRegistry::NotifyContextDestroy(Context* context)
 void PluginRegistry::NotifyContextDestroy(Context* context)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnContextDestroy(context);
+	for (size_t i = 0; i < basic_plugins.size(); ++i)
+		basic_plugins[i]->OnContextDestroy(context);
 }
 }
 
 
 // Calls OnDocumentOpen() on all plugins.
 // Calls OnDocumentOpen() on all plugins.
 void PluginRegistry::NotifyDocumentOpen(Context* context, const String& document_path)
 void PluginRegistry::NotifyDocumentOpen(Context* context, const String& document_path)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnDocumentOpen(context, document_path);
+	for (size_t i = 0; i < document_plugins.size(); ++i)
+		document_plugins[i]->OnDocumentOpen(context, document_path);
 }
 }
 
 
 // Calls OnDocumentLoad() on all plugins.
 // Calls OnDocumentLoad() on all plugins.
 void PluginRegistry::NotifyDocumentLoad(ElementDocument* document)
 void PluginRegistry::NotifyDocumentLoad(ElementDocument* document)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnDocumentLoad(document);
+	for (size_t i = 0; i < document_plugins.size(); ++i)
+		document_plugins[i]->OnDocumentLoad(document);
 }
 }
 
 
 // Calls OnDocumentUnload() on all plugins.
 // Calls OnDocumentUnload() on all plugins.
 void PluginRegistry::NotifyDocumentUnload(ElementDocument* document)
 void PluginRegistry::NotifyDocumentUnload(ElementDocument* document)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnDocumentUnload(document);
+	for (size_t i = 0; i < document_plugins.size(); ++i)
+		document_plugins[i]->OnDocumentUnload(document);
 }
 }
 
 
 // Calls OnElementCreate() on all plugins.
 // Calls OnElementCreate() on all plugins.
 void PluginRegistry::NotifyElementCreate(Element* element)
 void PluginRegistry::NotifyElementCreate(Element* element)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnElementCreate(element);
+	for (size_t i = 0; i < element_plugins.size(); ++i)
+		element_plugins[i]->OnElementCreate(element);
 }
 }
 
 
 // Calls OnElementDestroy() on all plugins.
 // Calls OnElementDestroy() on all plugins.
 void PluginRegistry::NotifyElementDestroy(Element* element)
 void PluginRegistry::NotifyElementDestroy(Element* element)
 {
 {
-	for (size_t i = 0; i < plugins.size(); ++i)
-		plugins[i]->OnElementDestroy(element);
+	for (size_t i = 0; i < element_plugins.size(); ++i)
+		element_plugins[i]->OnElementDestroy(element);
 }
 }
 
 
 }
 }

+ 0 - 1
Source/Core/PluginRegistry.h

@@ -69,7 +69,6 @@ public:
 
 
 private:
 private:
 	PluginRegistry();
 	PluginRegistry();
-	~PluginRegistry();
 };
 };
 
 
 }
 }

+ 5 - 4
Source/Debugger/Debugger.cpp

@@ -32,18 +32,16 @@
 namespace Rocket {
 namespace Rocket {
 namespace Debugger {
 namespace Debugger {
 
 
-static Plugin* plugin = NULL;
-
 // Initialises the debug plugin. The debugger will be loaded into the given context.
 // Initialises the debug plugin. The debugger will be loaded into the given context.
 bool Initialise(Core::Context* context)
 bool Initialise(Core::Context* context)
 {
 {
-	if (plugin != NULL)
+	if (Plugin::GetInstance() != NULL)
 	{
 	{
 		Core::Log::Message(Core::Log::LT_WARNING, "Unable to initialise debugger plugin, already initialised!");
 		Core::Log::Message(Core::Log::LT_WARNING, "Unable to initialise debugger plugin, already initialised!");
 		return false;
 		return false;
 	}
 	}
 
 
-	plugin = new Plugin();
+	Plugin* plugin = new Plugin();
 	if (!plugin->Initialise(context))
 	if (!plugin->Initialise(context))
 	{
 	{
 		Core::Log::Message(Core::Log::LT_WARNING, "Unable to initialise debugger plugin.");
 		Core::Log::Message(Core::Log::LT_WARNING, "Unable to initialise debugger plugin.");
@@ -61,6 +59,7 @@ bool Initialise(Core::Context* context)
 // Sets the context to be debugged.
 // Sets the context to be debugged.
 bool SetContext(Core::Context* context)
 bool SetContext(Core::Context* context)
 {
 {
+	Plugin* plugin = Plugin::GetInstance();
 	if (plugin == NULL)
 	if (plugin == NULL)
 		return false;
 		return false;
 
 
@@ -72,6 +71,7 @@ bool SetContext(Core::Context* context)
 // Sets the visibility of the debugger.
 // Sets the visibility of the debugger.
 void SetVisible(bool visibility)
 void SetVisible(bool visibility)
 {
 {
+	Plugin* plugin = Plugin::GetInstance();
 	if (plugin != NULL)
 	if (plugin != NULL)
 		plugin->SetVisible(visibility);
 		plugin->SetVisible(visibility);
 }
 }
@@ -79,6 +79,7 @@ void SetVisible(bool visibility)
 // Returns the visibility of the debugger.
 // Returns the visibility of the debugger.
 bool IsVisible()
 bool IsVisible()
 {
 {
+	Plugin* plugin = Plugin::GetInstance();
 	if (plugin == NULL)
 	if (plugin == NULL)
 		return false;
 		return false;
 
 

+ 10 - 0
Source/Debugger/Plugin.cpp

@@ -40,8 +40,12 @@
 namespace Rocket {
 namespace Rocket {
 namespace Debugger {
 namespace Debugger {
 
 
+Plugin* Plugin::instance = NULL;
+
 Plugin::Plugin()
 Plugin::Plugin()
 {
 {
+	ROCKET_ASSERT(instance == NULL);
+	instance = this;
 	host_context = NULL;
 	host_context = NULL;
 	debug_context = NULL;
 	debug_context = NULL;
 	log_hook = NULL;
 	log_hook = NULL;
@@ -55,6 +59,7 @@ Plugin::Plugin()
 
 
 Plugin::~Plugin()
 Plugin::~Plugin()
 {
 {
+	instance = NULL;
 }
 }
 
 
 // Initialises the debugging tools into the given context.
 // Initialises the debugging tools into the given context.
@@ -272,6 +277,11 @@ void Plugin::ProcessEvent(Core::Event& event)
 	}
 	}
 }
 }
 
 
+Plugin* Plugin::GetInstance()
+{
+	return instance;
+}
+
 bool Plugin::LoadFont()
 bool Plugin::LoadFont()
 {
 {
 	return (Core::FontDatabase::LoadFontFace(lacuna_regular, sizeof(lacuna_regular) / sizeof(unsigned char), "Lacuna", Core::Font::STYLE_NORMAL, Core::Font::WEIGHT_NORMAL) &&
 	return (Core::FontDatabase::LoadFontFace(lacuna_regular, sizeof(lacuna_regular) / sizeof(unsigned char), "Lacuna", Core::Font::STYLE_NORMAL, Core::Font::WEIGHT_NORMAL) &&

+ 7 - 0
Source/Debugger/Plugin.h

@@ -96,6 +96,10 @@ public:
 	/// @param[in] event The event to process.
 	/// @param[in] event The event to process.
 	virtual void ProcessEvent(Core::Event& event);
 	virtual void ProcessEvent(Core::Event& event);
 
 
+	/// Access the singleton instance of the debugger
+	/// @return NULL or an instance of the plugin
+	static Plugin* GetInstance();
+
 private:
 private:
 	bool LoadFont();
 	bool LoadFont();
 	bool LoadMenuElement();
 	bool LoadMenuElement();
@@ -123,6 +127,9 @@ private:
 	// Keep track of instanced elements for leak tracking.
 	// Keep track of instanced elements for leak tracking.
 	typedef std::set< Core::Element* > ElementInstanceMap;
 	typedef std::set< Core::Element* > ElementInstanceMap;
 	ElementInstanceMap elements;
 	ElementInstanceMap elements;
+
+	// Singleton instance
+	static Plugin* instance;
 };
 };
 
 
 }
 }