mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 01:56:43 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			235 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef SH_PROPERTYBASE_H
 | |
| #define SH_PROPERTYBASE_H
 | |
| 
 | |
| #include <string>
 | |
| #include <map>
 | |
| 
 | |
| #include <boost/shared_ptr.hpp>
 | |
| 
 | |
| namespace sh
 | |
| {
 | |
| 	class StringValue;
 | |
| 	class PropertySetGet;
 | |
| 	class LinkedValue;
 | |
| 
 | |
| 	enum ValueType
 | |
| 	{
 | |
| 		VT_String,
 | |
| 		VT_Int,
 | |
| 		VT_Float,
 | |
| 		VT_Vector2,
 | |
| 		VT_Vector3,
 | |
| 		VT_Vector4
 | |
| 	};
 | |
| 
 | |
| 	class PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		PropertyValue() {}
 | |
| 
 | |
| 		virtual ~PropertyValue() {}
 | |
| 
 | |
| 		std::string _getStringValue() { return mStringValue; }
 | |
| 
 | |
| 		virtual std::string serialize() = 0;
 | |
| 
 | |
| 	protected:
 | |
| 		std::string mStringValue; ///< this will possibly not contain anything in the specialised classes
 | |
| 	};
 | |
| 	typedef boost::shared_ptr<PropertyValue> PropertyValuePtr;
 | |
| 
 | |
| 	class StringValue : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		StringValue (const std::string& in);
 | |
| 		std::string get() const { return mStringValue; }
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	};
 | |
| 
 | |
| 	/**
 | |
| 	 * @brief Used for retrieving a named property from a context
 | |
| 	 */
 | |
| 	class LinkedValue : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		LinkedValue (const std::string& in);
 | |
| 
 | |
| 		std::string get(PropertySetGet* context) const;
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	};
 | |
| 
 | |
| 	class FloatValue : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		FloatValue (float in);
 | |
| 		FloatValue (const std::string& in);
 | |
| 		float get() const { return mValue; }
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	private:
 | |
| 		float mValue;
 | |
| 	};
 | |
| 
 | |
| 	class IntValue : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		IntValue (int in);
 | |
| 		IntValue (const std::string& in);
 | |
| 		int get() const { return mValue; }
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	private:
 | |
| 		int mValue;
 | |
| 	};
 | |
| 
 | |
| 	class BooleanValue : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		BooleanValue (bool in);
 | |
| 		BooleanValue (const std::string& in);
 | |
| 		bool get() const { return mValue; }
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	private:
 | |
| 		bool mValue;
 | |
| 	};
 | |
| 
 | |
| 	class Vector2 : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		Vector2 (float x, float y);
 | |
| 		Vector2 (const std::string& in);
 | |
| 
 | |
| 		float mX, mY;
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	};
 | |
| 
 | |
| 	class Vector3 : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		Vector3 (float x, float y, float z);
 | |
| 		Vector3 (const std::string& in);
 | |
| 
 | |
| 		float mX, mY, mZ;
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	};
 | |
| 
 | |
| 	class Vector4 : public PropertyValue
 | |
| 	{
 | |
| 	public:
 | |
| 		Vector4 (float x, float y, float z, float w);
 | |
| 		Vector4 (const std::string& in);
 | |
| 
 | |
| 		float mX, mY, mZ, mW;
 | |
| 
 | |
| 		virtual std::string serialize();
 | |
| 	};
 | |
| 
 | |
| 	/// \brief base class that allows setting properties with any kind of value-type
 | |
| 	class PropertySet
 | |
| 	{
 | |
| 	public:
 | |
| 		void setProperty (const std::string& name, PropertyValuePtr& value, PropertySetGet* context);
 | |
| 
 | |
| 	protected:
 | |
| 		virtual bool setPropertyOverride (const std::string& name, PropertyValuePtr& value, PropertySetGet* context);
 | |
| 		///< @return \a true if the specified property was found, or false otherwise
 | |
| 	};
 | |
| 
 | |
| 	typedef std::map<std::string, PropertyValuePtr> PropertyMap;
 | |
| 
 | |
| 	/// \brief base class that allows setting properties with any kind of value-type and retrieving them
 | |
| 	class PropertySetGet
 | |
| 	{
 | |
| 	public:
 | |
| 		PropertySetGet (PropertySetGet* parent);
 | |
| 		PropertySetGet ();
 | |
| 
 | |
| 		virtual ~PropertySetGet() {}
 | |
| 
 | |
| 		void copyAll (PropertySet* target, PropertySetGet* context); ///< call setProperty for each property/value pair stored in \a this
 | |
| 
 | |
| 		void setParent (PropertySetGet* parent);
 | |
| 		void setContext (PropertySetGet* context);
 | |
| 		PropertySetGet* getContext();
 | |
| 
 | |
| 		virtual void setProperty (const std::string& name, PropertyValuePtr value);
 | |
| 		PropertyValuePtr& getProperty (const std::string& name);
 | |
| 
 | |
| 		const PropertyMap& listProperties() { return mProperties; }
 | |
| 
 | |
| 		bool hasProperty (const std::string& name);
 | |
| 
 | |
| 	private:
 | |
| 		PropertyMap mProperties;
 | |
| 
 | |
| 	protected:
 | |
| 		PropertySetGet* mParent;
 | |
| 		///< the parent can provide properties as well (when they are retrieved via getProperty) \n
 | |
| 		/// multiple levels of inheritance are also supported \n
 | |
| 		/// children can override properties of their parents
 | |
| 
 | |
| 		PropertySetGet* mContext;
 | |
| 		///< used to retrieve linked property values
 | |
| 	};
 | |
| 
 | |
| 	template <typename T>
 | |
| 	static T retrieveValue (boost::shared_ptr<PropertyValue>& value, PropertySetGet* context)
 | |
| 	{
 | |
| 		if (typeid(*value).name() == typeid(LinkedValue).name())
 | |
| 		{
 | |
| 			std::string v = static_cast<LinkedValue*>(value.get())->get(context);
 | |
| 			PropertyValuePtr newVal = PropertyValuePtr (new StringValue(v));
 | |
| 			return retrieveValue<T>(newVal, NULL);
 | |
| 		}
 | |
| 		if (typeid(T).name() == typeid(*value).name())
 | |
| 		{
 | |
| 			// requested type is the same as source type, only have to cast it
 | |
| 			return *static_cast<T*>(value.get());
 | |
| 		}
 | |
| 
 | |
| 		if ((typeid(T).name() == typeid(StringValue).name())
 | |
| 			&& typeid(*value).name() != typeid(StringValue).name())
 | |
| 		{
 | |
| 			// if string type is requested and value is not string, use serialize method to convert to string
 | |
| 			T* ptr = new T (value->serialize()); // note that T is always StringValue here, but we can't use it here
 | |
| 			value = boost::shared_ptr<PropertyValue> (static_cast<PropertyValue*>(ptr));
 | |
| 			return *ptr;
 | |
| 		}
 | |
| 
 | |
| 		{
 | |
| 			// remaining case: deserialization from string by passing the string to constructor of class T
 | |
| 			T* ptr = new T(value->_getStringValue());
 | |
| 			PropertyValuePtr newVal (static_cast<PropertyValue*>(ptr));
 | |
| 			value = newVal;
 | |
| 			return *ptr;
 | |
| 		}
 | |
| 	}
 | |
| 	///<
 | |
| 	/// @brief alternate version that supports linked values (use of $variables in parent material)
 | |
| 	/// @note \a value is changed in-place to the converted object
 | |
| 	/// @return converted object \n
 | |
| 
 | |
| 	/// Create a property from a string
 | |
| 	inline PropertyValuePtr makeProperty (const std::string& prop)
 | |
| 	{
 | |
| 		if (prop.size() > 1 && prop[0] == '$')
 | |
| 			return PropertyValuePtr (static_cast<PropertyValue*>(new LinkedValue(prop)));
 | |
| 		else
 | |
| 			return PropertyValuePtr (static_cast<PropertyValue*> (new StringValue(prop)));
 | |
| 	}
 | |
| 
 | |
| 	template <typename T>
 | |
| 	/// Create a property of any type
 | |
| 	/// Example: sh::makeProperty\<sh::Vector4\> (new sh::Vector4(1, 1, 1, 1))
 | |
| 	inline PropertyValuePtr makeProperty (T* p)
 | |
| 	{
 | |
| 		return PropertyValuePtr ( static_cast<PropertyValue*>(p) );
 | |
| 	}
 | |
| }
 | |
| 
 | |
| #endif
 |