Browse Source

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 years ago
parent
commit
0e8316e5b4

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

@@ -48,8 +48,20 @@ class ROCKETCORE_API Plugin
 public:
 	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();
 	/// Called when Rocket shuts down.
 	virtual void OnShutdown();

+ 22 - 2
Source/Controls/Controls.cpp

@@ -30,6 +30,8 @@
 #include <Rocket/Core/Factory.h>
 #include <Rocket/Core/StyleSheetSpecification.h>
 #include <Rocket/Core/XMLParser.h>
+#include <Rocket/Core/Plugin.h>
+#include <Rocket/Core/Core.h>
 #include "ElementTextSelection.h"
 #include "XMLNodeHandlerDataGrid.h"
 #include "XMLNodeHandlerTabSet.h"
@@ -102,10 +104,25 @@ void RegisterXMLNodeHandlers()
 	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
 	if (!initialised)
 	{
@@ -117,6 +134,9 @@ void Initialise()
 		// Register the XML node handlers for our elements that require special parsing.
 		RegisterXMLNodeHandlers();
 
+		// Register the controls plugin, so we'll be notified on Shutdown
+		Rocket::Core::RegisterPlugin(new ControlsPlugin());
+
 		initialised = true;
 	}
 }

+ 4 - 7
Source/Core/Core.cpp

@@ -34,13 +34,6 @@
 #include "StyleSheetFactory.h"
 #include "TemplateCache.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 Core {
@@ -146,6 +139,10 @@ void Shutdown()
 
 	if (system_interface != NULL)
 		system_interface->RemoveReference();
+	
+	render_interface = NULL;
+	file_interface = NULL;
+	system_interface = NULL;
 		
 	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)
 		(*i).second->RemoveReference();
+	element_instancers.clear();
 
 	for (DecoratorInstancerMap::iterator i = decorator_instancers.begin(); i != decorator_instancers.end(); ++i)
 		(*i).second->RemoveReference();
+	decorator_instancers.clear();
 
 	for (FontEffectInstancerMap::iterator i = font_effect_instancers.begin(); i != font_effect_instancers.end(); ++i)
 		(*i).second->RemoveReference();
+	font_effect_instancers.clear();
 
 	if (context_instancer)
 		context_instancer->RemoveReference();
+	context_instancer = NULL;
 
 	if (event_listener_instancer)
 		event_listener_instancer->RemoveReference();
+	event_listener_instancer = NULL;
 
 	if (event_instancer)
 		event_instancer->RemoveReference();
+	event_instancer = NULL;
 
 	XMLParser::ReleaseHandlers();
 }

+ 5 - 0
Source/Core/Plugin.cpp

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

+ 32 - 25
Source/Core/PluginRegistry.cpp

@@ -33,85 +33,92 @@ namespace Rocket {
 namespace Core {
 
 typedef std::vector< Plugin* > PluginList;
-PluginList plugins;
+static PluginList basic_plugins;
+static PluginList document_plugins;
+static PluginList element_plugins;
 
 PluginRegistry::PluginRegistry()
 {
 }
 
-PluginRegistry::~PluginRegistry()
-{
-}
-
 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.
 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.
 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.
 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.
 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.
 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.
 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.
 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.
 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.
 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:
 	PluginRegistry();
-	~PluginRegistry();
 };
 
 }

+ 5 - 4
Source/Debugger/Debugger.cpp

@@ -32,18 +32,16 @@
 namespace Rocket {
 namespace Debugger {
 
-static Plugin* plugin = NULL;
-
 // Initialises the debug plugin. The debugger will be loaded into the given 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!");
 		return false;
 	}
 
-	plugin = new Plugin();
+	Plugin* plugin = new Plugin();
 	if (!plugin->Initialise(context))
 	{
 		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.
 bool SetContext(Core::Context* context)
 {
+	Plugin* plugin = Plugin::GetInstance();
 	if (plugin == NULL)
 		return false;
 
@@ -72,6 +71,7 @@ bool SetContext(Core::Context* context)
 // Sets the visibility of the debugger.
 void SetVisible(bool visibility)
 {
+	Plugin* plugin = Plugin::GetInstance();
 	if (plugin != NULL)
 		plugin->SetVisible(visibility);
 }
@@ -79,6 +79,7 @@ void SetVisible(bool visibility)
 // Returns the visibility of the debugger.
 bool IsVisible()
 {
+	Plugin* plugin = Plugin::GetInstance();
 	if (plugin == NULL)
 		return false;
 

+ 10 - 0
Source/Debugger/Plugin.cpp

@@ -40,8 +40,12 @@
 namespace Rocket {
 namespace Debugger {
 
+Plugin* Plugin::instance = NULL;
+
 Plugin::Plugin()
 {
+	ROCKET_ASSERT(instance == NULL);
+	instance = this;
 	host_context = NULL;
 	debug_context = NULL;
 	log_hook = NULL;
@@ -55,6 +59,7 @@ Plugin::Plugin()
 
 Plugin::~Plugin()
 {
+	instance = NULL;
 }
 
 // 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()
 {
 	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.
 	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:
 	bool LoadFont();
 	bool LoadMenuElement();
@@ -123,6 +127,9 @@ private:
 	// Keep track of instanced elements for leak tracking.
 	typedef std::set< Core::Element* > ElementInstanceMap;
 	ElementInstanceMap elements;
+
+	// Singleton instance
+	static Plugin* instance;
 };
 
 }