فهرست منبع

Merge pull request #1214 from Pixelized/controls_factory

Use of a control factory to instantiate controls (follow-up of #1192)
Sean Taylor 12 سال پیش
والد
کامیت
6014132109

+ 2 - 0
gameplay/CMakeLists.txt

@@ -48,6 +48,8 @@ set(GAMEPLAY_SRC
     src/Container.h
     src/Control.cpp
     src/Control.h
+	src/ControlFactory.h
+	src/ControlFactory.cpp
     src/Curve.cpp
     src/Curve.h
     src/DebugNew.cpp

+ 1 - 1
gameplay/src/Button.cpp

@@ -23,7 +23,7 @@ Button* Button::create(const char* id, Theme::Style* style)
     return button;
 }
 
-Button* Button::create(Theme::Style* style, Properties* properties)
+Control* Button::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     Button* button = new Button();
     button->initialize(style, properties);

+ 4 - 2
gameplay/src/Button.h

@@ -35,6 +35,7 @@ class Button : public Label
 {
     friend class Container;
     friend class Gamepad;
+	friend class ControlFactory;
 
 public:
 
@@ -66,10 +67,11 @@ protected:
      *
      * @param style The style to apply to this button.
      * @param properties The properties to set on this button.
-     *
+     * @param theme The theme to set on this control if needed.
+	 *
      * @return The new button.
      */
-    static Button* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.

+ 1 - 1
gameplay/src/CheckBox.cpp

@@ -26,7 +26,7 @@ CheckBox* CheckBox::create(const char* id, Theme::Style* style)
     return checkBox;
 }
 
-CheckBox* CheckBox::create(Theme::Style* style, Properties* properties)
+Control* CheckBox::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     GP_ASSERT(properties);
 

+ 4 - 2
gameplay/src/CheckBox.h

@@ -35,6 +35,7 @@ namespace gameplay
 class CheckBox : public Button
 {
     friend class Container;
+	friend class ControlFactory;
 
 public:
 
@@ -112,10 +113,11 @@ protected:
      *
      * @param style The style to apply to this checkbox.
      * @param properties The properties to set on this checkbox.
-     *
+     * @param theme The theme to set on this control if needed
+	 *
      * @return The new checkbox.
      */
-    static CheckBox* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.

+ 3 - 43
gameplay/src/Container.cpp

@@ -13,6 +13,7 @@
 #include "Joystick.h"
 #include "ImageControl.h"
 #include "Game.h"
+#include "ControlFactory.h"
 
 namespace gameplay
 {
@@ -111,7 +112,7 @@ Container* Container::create(Layout::Type type)
     return container;
 }
 
-Container* Container::create(Theme::Style* style, Properties* properties, Theme* theme)
+Control* Container::create(Theme::Style* style, Properties* properties, Theme* theme)
 {
     GP_ASSERT(properties);
 
@@ -181,48 +182,7 @@ void Container::addControls(Theme* theme, Properties* properties)
 
         std::string controlName(controlSpace->getNamespace());
         std::transform(controlName.begin(), controlName.end(), controlName.begin(), (int(*)(int))toupper);
-        if (controlName == "LABEL")
-        {
-            control = Label::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "BUTTON")
-        {
-            control = Button::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "CHECKBOX")
-        {
-            control = CheckBox::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "RADIOBUTTON")
-        {
-            control = RadioButton::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "CONTAINER")
-        {
-            control = Container::create(controlStyle, controlSpace, theme);
-        }
-        else if (controlName == "SLIDER")
-        {
-            control = Slider::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "TEXTBOX")
-        {
-            control = TextBox::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "JOYSTICK")
-        {
-            control = Joystick::create(controlStyle, controlSpace);
-        }
-        else if (controlName == "IMAGE")
-        {
-            control = ImageControl::create(controlStyle, controlSpace);
-        }
-        else
-        {
-            // Ignore - not a valid control name.
-            // This used to fail, but I see no reason to hard fail here (this also fixes not being able
-            // to set padding on containers).
-        }
+		control = ControlFactory::getInstance().createControl(controlName, controlStyle, controlSpace, theme);
 
         // Add the new control to the form.
         if (control)

+ 2 - 1
gameplay/src/Container.h

@@ -50,6 +50,7 @@ namespace gameplay
  */
 class Container : public Control, TimeListener
 {
+	friend class ControlFactory;
 
 public:
 
@@ -299,7 +300,7 @@ protected:
      *
      * @return The new container.
      */
-    static Container* create(Theme::Style* style, Properties* properties, Theme* theme);
+    static Control* create(Theme::Style* style, Properties* properties, Theme* theme);
 
     /**
      * Updates each control within this container,

+ 61 - 0
gameplay/src/ControlFactory.cpp

@@ -0,0 +1,61 @@
+#include "ControlFactory.h"
+
+#include "Label.h"
+#include "Button.h"
+#include "CheckBox.h"
+#include "RadioButton.h"
+#include "Container.h"
+#include "Slider.h"
+#include "TextBox.h"
+#include "Joystick.h"
+#include "ImageControl.h"
+
+#include <iostream>
+
+namespace gameplay {
+
+	ControlFactory::ControlFactory() {
+		registerStdControls();
+	}
+
+	ControlFactory::~ControlFactory() {}
+
+	ControlFactory &ControlFactory::getInstance() {
+		static ControlFactory instance;
+
+		return instance;
+	}
+
+	bool ControlFactory::registerCustomControl(const std::string &name, ControlActivator controlCreator) {
+		if (_registeredControls.find(name) != _registeredControls.end())
+			return false;
+		_registeredControls[name] = controlCreator;
+		return true;
+	}
+
+	void ControlFactory::unregisterCustomControl(const std::string &name) {
+		std::map<std::string, ControlActivator>::iterator it;
+
+		if ((it = _registeredControls.find(name)) != _registeredControls.end())
+			_registeredControls.erase(it);
+	}
+
+	Control *ControlFactory::createControl(const std::string &name, Theme::Style *style, Properties *properties, Theme *theme) {
+		if (_registeredControls.find(name) == _registeredControls.end())
+			return NULL;	
+		return (*_registeredControls[name])(style, properties, theme);
+	}
+
+	void ControlFactory::registerStdControls() {
+		_registeredControls["LABEL"] = &Label::create;
+		_registeredControls["BUTTON"] = &Button::create;
+		_registeredControls["CHECKBOX"] = &CheckBox::create;
+		_registeredControls["RADIOBUTTON"] = &RadioButton::create;
+		_registeredControls["CONTAINER"] = &Container::create;
+		_registeredControls["SLIDER"] = &Slider::create;
+		_registeredControls["TEXTBOX"] = &TextBox::create;
+		_registeredControls["JOYSTICK"] = &Joystick::create;
+		_registeredControls["IMAGE"] = &ImageControl::create;
+	}
+
+}

+ 39 - 0
gameplay/src/ControlFactory.h

@@ -0,0 +1,39 @@
+#ifndef	CONTROLFACTORY_H_
+#define	CONTROLFACTORY_H_
+
+#include <map>
+#include <string>
+
+#include "Theme.h"
+
+namespace gameplay {
+	
+	class Properties;
+	class Control;
+
+	class ControlFactory {
+		
+		public :
+			typedef Control *(*ControlActivator)(Theme::Style *, Properties *, Theme *);
+
+			static ControlFactory	&getInstance();
+
+			bool					registerCustomControl(const std::string &controlName, ControlActivator controlCreator);
+			void					unregisterCustomControl(const std::string &controlName);
+			Control					*createControl(const std::string &controlName, Theme::Style *style, Properties *properties, Theme *theme = NULL);
+
+		private :
+			std::map<std::string, ControlActivator>	_registeredControls;
+			
+			ControlFactory();
+			ControlFactory(const ControlFactory &);
+			~ControlFactory();
+
+			ControlFactory &operator=(const ControlFactory &);
+	
+			void 			registerStdControls();
+	};
+}
+
+#endif	//CONTROLFACTORY_H_
+

+ 1 - 1
gameplay/src/ImageControl.cpp

@@ -30,7 +30,7 @@ ImageControl* ImageControl::create(const char* id, Theme::Style* style)
     return imageControl;
 }
 
-ImageControl* ImageControl::create(Theme::Style* style, Properties* properties)
+Control* ImageControl::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     ImageControl* imageControl = new ImageControl();
     imageControl->initialize(style, properties);

+ 3 - 2
gameplay/src/ImageControl.h

@@ -36,6 +36,7 @@ namespace gameplay
 class ImageControl : public Button
 {
     friend class Container;
+	friend class ControlFactory;
 
 public:
 
@@ -117,7 +118,7 @@ protected:
     
     virtual ~ImageControl();
 
-    static ImageControl* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     virtual void initialize(Theme::Style* style, Properties* properties);
 
@@ -148,4 +149,4 @@ private:
 
 }
 
-#endif
+#endif

+ 1 - 1
gameplay/src/Joystick.cpp

@@ -28,7 +28,7 @@ Joystick* Joystick::create(const char* id, Theme::Style* style)
     return joystick;
 }
 
-Joystick* Joystick::create(Theme::Style* style, Properties* properties)
+Control* Joystick::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     Joystick* joystick = new Joystick();
     joystick->initialize(style, properties);

+ 4 - 2
gameplay/src/Joystick.h

@@ -25,6 +25,7 @@ class Joystick : public Control
 {
     friend class Container;
     friend class Gamepad;
+	friend class ControlFactory;
 
 public:
 
@@ -137,10 +138,11 @@ protected:
      *
      * @param style The style to apply to this joystick.
      * @param properties The properties to set on this joystick.
-     *
+     * @param theme The theme to set on this control if needed.
+	 *
      * @return The new joystick.
      */
-    static Joystick* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Initialize this joystick.

+ 2 - 2
gameplay/src/Label.cpp

@@ -30,12 +30,12 @@ Label* Label::create(const char* id, Theme::Style* style)
     return label;
 }
 
-Label* Label::create(Theme::Style* style, Properties* properties)
+Control* Label::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     Label* label = new Label();
     label->initialize(style, properties);
 
-    label->_consumeInputEvents = false;
+	label->_consumeInputEvents = false;
     label->_focusIndex = -2;
 
     return label;

+ 4 - 2
gameplay/src/Label.h

@@ -31,6 +31,7 @@ namespace gameplay
 class Label : public Control
 {
     friend class Container;
+	friend class ControlFactory;
 
 public:
 
@@ -93,10 +94,11 @@ protected:
      *
      * @param style The style to apply to this label.
      * @param properties The properties to set on this label.
-     *
+     * @param theme The theme to set on this control if needed
+	 * 
      * @return The new label.
      */
-    static Label* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Initialize this label.

+ 1 - 1
gameplay/src/RadioButton.cpp

@@ -33,7 +33,7 @@ RadioButton* RadioButton::create(const char* id, Theme::Style* style)
     return radioButton;
 }
 
-RadioButton* RadioButton::create(Theme::Style* style, Properties* properties)
+Control* RadioButton::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     GP_ASSERT(properties);
 

+ 4 - 2
gameplay/src/RadioButton.h

@@ -37,6 +37,7 @@ namespace gameplay
 class RadioButton : public Button
 {
     friend class Container;
+	friend class ControlFactory;
 
 public:
 
@@ -125,10 +126,11 @@ protected:
      *
      * @param style The style to apply to this radio button.
      * @param properties The properties to set on this radio button.
-     *
+     * @param theme The theme to set on this control if needed
+	 *
      * @return The new radio button.
      */
-    static RadioButton* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.

+ 1 - 1
gameplay/src/Slider.cpp

@@ -35,7 +35,7 @@ Slider* Slider::create(const char* id, Theme::Style* style)
     return slider;
 }
 
-Slider* Slider::create(Theme::Style* style, Properties* properties)
+Control* Slider::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     GP_ASSERT(properties);
 

+ 4 - 2
gameplay/src/Slider.h

@@ -33,6 +33,7 @@ namespace gameplay
 class Slider : public Label
 {
     friend class Container;
+	friend class ControlFactory;
 
 public:
 
@@ -181,10 +182,11 @@ protected:
      *
      * @param style The style to apply to this slider.
      * @param properties The properties to set on this slider.
-     *
+     * @param theme The theme to set on this control if needed
+	 *
      * @return The new slider.
      */
-    static Slider* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.

+ 1 - 1
gameplay/src/TextBox.cpp

@@ -28,7 +28,7 @@ TextBox* TextBox::create(const char* id, Theme::Style* style)
     return textBox;
 }
 
-TextBox* TextBox::create(Theme::Style* style, Properties* properties)
+Control* TextBox::create(Theme::Style* style, Properties* properties, Theme *theme)
 {
     TextBox* textBox = new TextBox();
     textBox->initialize(style, properties);

+ 5 - 3
gameplay/src/TextBox.h

@@ -37,7 +37,8 @@ namespace gameplay
 class TextBox : public Label
 {
     friend class Container;
-
+	friend class ControlFactory;
+	
 public:
 
     /**
@@ -140,10 +141,11 @@ protected:
      *
      * @param style The style to apply to this text box.
      * @param properties The properties to set on this text box.
-     *
+     * @param theme The theme to set on this control if needed
+	 *
      * @return The new text box.
      */
-    static TextBox* create(Theme::Style* style, Properties* properties);
+    static Control* create(Theme::Style* style, Properties* properties, Theme *theme = NULL);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.