Commits

Anonymous committed 7aafb79

Updated component system
Updated Python wrapper

Comments (0)

Files changed (36)

PolyMain/include/game/PolyAudioListenerComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(AudioListenerComponent, "AudioListener", "AudioListener");
+	POLY_CLASS_IMPL(AudioListenerComponent,);
 
 	AudioListenerComponent::AudioListenerComponent() {
 		gEnv.audio->_registerComponent(this);

PolyMain/include/game/PolyAudioListenerComponent.h

 		// Serialization
 		virtual void			serialize(StringVariantMap& params) const;
 
-								POLY_COMPONENT_BASE;
+		POLY_CLASS;
 	};
 }
 

PolyMain/include/game/PolyBoxColliderComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(BoxColliderComponent, "BoxCollider", "BoxCollider");
+	POLY_CLASS_IMPL(BoxColliderComponent,);
 
 	BoxColliderComponent::BoxColliderComponent()
 	:	mOffset(Vector3::ZERO) {
-		mProperties.addProperty("BoxCollider/Extends", &mExtends);
-		mProperties.addProperty("BoxCollider/Offset", &mOffset, true);
+		mProperties.addProperty("Extends", &mExtends);
+		mProperties.addProperty("Offset", &mOffset, true);
 	}
 
 	void BoxColliderComponent::_notifyOtherComponentAdded(Component* other) {
-		if(other->getFamilyName() != PhysicsComponent::GetFamilyName())
+		if(other->getRuntimeTypeInfo().name != PhysicsComponent::GetTypeInfo().name)
 			return;
 
 		physx::PxMaterial* defaultMaterial = gEnv.physics->getDefaultMaterial();
-
 		physx::PxTransform transform = PhysicsUtil::convert(mOffset, Quaternion::IDENTITY);
 
 		PhysicsComponent* physicsC = static_cast<PhysicsComponent*>(other);

PolyMain/include/game/PolyBoxColliderComponent.h

 namespace Poly {
 	class _PolyExport BoxColliderComponent : public Component {
 	public:
-		BoxColliderComponent();
+						BoxColliderComponent();
 
-		virtual void _notifyOtherComponentAdded(Component* other);
+		virtual void	_notifyOtherComponentAdded(Component* other);
 
-		POLY_COMPONENT_BASE;
+		POLY_CLASS;
 
 	protected:
-		Vector3 mExtends;
-		Vector3 mOffset;
+		Vector3			mExtends;
+		Vector3			mOffset;
 	};
 }
 

PolyMain/include/game/PolyCameraComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(CameraComponent, "Camera", "Camera");
+	POLY_CLASS_IMPL(CameraComponent,);
 
 	CameraComponent::CameraComponent()
 	:	sceneNode(POLY_NULLPTR) {
 	}
 
 	void CameraComponent::_notifyOtherComponentAdded(Component* other) {
-		if(other->getFamilyName() != TransformComponent::GetFamilyName())
+		if(other->getRuntimeTypeInfo().name != TransformComponent::GetTypeInfo().name)
 			return;
 		if(sceneNode)
 			return;

PolyMain/include/game/PolyCameraComponent.h

 		// Notifications
 		virtual void		_notifyOtherComponentAdded(Component* other);
 
-							POLY_COMPONENT_BASE;
+		POLY_CLASS;
 	};
 }
 

PolyMain/include/game/PolyCharacterControllerComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(CharacterControllerComponent, "CharacterController", "CharacterController");
+	POLY_CLASS_IMPL(CharacterControllerComponent,);
 
 	CharacterControllerComponent::CharacterControllerComponent() {
-		mProperties.addProperty("CharacterController/Height", (float*)POLY_NULLPTR);
-		mProperties.addProperty("CharacterController/Radius", (float*)POLY_NULLPTR);
-		mProperties.addProperty("CharacterController/SlopeLimit", (float*)POLY_NULLPTR, true);
-		mProperties.addProperty("CharacterController/StepOffset", (float*)POLY_NULLPTR, true);
-		mProperties.addProperty("CharacterController/ContactOffset", (float*)POLY_NULLPTR, true);
-		mProperties.addProperty("CharacterController/Offset", &offset, true);
+		mProperties.addProperty("Height", (float*)POLY_NULLPTR);
+		mProperties.addProperty("Radius", (float*)POLY_NULLPTR);
+		mProperties.addProperty("SlopeLimit", (float*)POLY_NULLPTR, true);
+		mProperties.addProperty("StepOffset", (float*)POLY_NULLPTR, true);
+		mProperties.addProperty("ContactOffset", (float*)POLY_NULLPTR, true);
+		mProperties.addProperty("Offset", &offset, true);
 	}
 
 	void CharacterControllerComponent::initialize(Entity entity, const StringVariantMap& values) {
 		Component::initialize(entity, values);
 
 		PhysicsCharacterControllerDesc desc;
-		desc.height = values.get<float>("CharacterController/Height", 2.0f);
-		desc.radius = values.get<float>("CharacterController/Radius", 0.9f);
-		desc.slopeLimit = values.get<float>("CharacterController/SlopeLimit", 0.707f);
-		desc.stepOffset = values.get<float>("CharacterController/StepOffset", 0.5f);
-		desc.contactOffset = values.get<float>("CharacterController/ContactOffset", 0.1f);
+		desc.height = values.get<float>("Height", 2.0f);
+		desc.radius = values.get<float>("Radius", 0.9f);
+		desc.slopeLimit = values.get<float>("SlopeLimit", 0.707f);
+		desc.stepOffset = values.get<float>("StepOffset", 0.5f);
+		desc.contactOffset = values.get<float>("ContactOffset", 0.1f);
 
 		controller = gEnv.physics->createCharacterController(entity.getLevel(), desc, entity);
 

PolyMain/include/game/PolyCharacterControllerComponent.h

 
 		virtual void			initialize(Entity entity, const StringVariantMap& values);
 
-		POLY_COMPONENT_BASE;
+		POLY_CLASS;
 	};
 }
 

PolyMain/include/game/PolyComponent.cpp

 
 
 namespace Poly {
+	POLY_CLASS_IMPL(Component,);
+
 	void Component::initialize(Entity entity, const StringVariantMap& values) {
 		mEntity = entity;
 

PolyMain/include/game/PolyComponent.h

 		PropertySet&			getProperties() { return mProperties; }
 		const PropertySet&		getProperties() const { return mProperties; }
 
-		// Type/family name
-		// Don't implement them yourself, use the POLY_COMPONENT_INFO macro!
-		virtual const InternString& getTypeName() const = 0;
-		virtual const InternString& getFamilyName() const = 0;
-
 		// Serialization
 		virtual void			save(IStream& bs) const {}
 		virtual void			load(IStream& bs) {}
 		virtual void			_notifyOtherComponentAdded(Component* other) {}
 		virtual void			_notifyOtherComponentRemoved(Component* other) {}
 
+		POLY_CLASS;
+
 	protected:
 		/// The owner.
 		Entity					mEntity;
 	}
 }
 
-// Add this to a base class of a new Component family.
-#define POLY_COMPONENT_BASE \
-	public: \
-		static const InternString& GetTypeName() { return msTypeName; } \
-		virtual const InternString& getTypeName() const { return msTypeName; } \
-		static const InternString& GetFamilyName() { return msFamilyName; } \
-		virtual const InternString& getFamilyName() const { return msFamilyName; } \
-	private: \
-		static InternString msTypeName; \
-		static InternString msFamilyName;
-
-// Add this to a child class of a Component family.
-#define POLY_COMPONENT_CHILD \
-	public: \
-	static const InternString& GetTypeName() { return msTypeName; } \
-	virtual const InternString& getTypeName() const { return msTypeName; } \
-	private: \
-	static InternString msTypeName;
-
-#define POLY_COMPONENT_BASE_IMPL(ComponentType, typeName, familyName) \
-	InternString ComponentType::msTypeName(typeName); \
-	InternString ComponentType::msFamilyName(familyName);
-
-#define POLY_COMPONENT_CHILD_IMPL(ComponentType, typeName) \
-	InternString ComponentType::msTypeName(typeName);
-
 #endif

PolyMain/include/game/PolyComponentFactory.h

 	public:
 		virtual				~IComponentFactory() {}
 
-		virtual Component* create(Entity entity, const StringVariantMap& values) const = 0;
-
-		void				setFamilyName(const InternString& familyName);
-		const InternString&	getFamilyName() const;
+		virtual Component*	create(Entity entity, const StringVariantMap& values) const = 0;
 
 	protected:
-		InternString		mFamilyName;
-
 							IComponentFactory() {}
 	};
 
-	inline void IComponentFactory::setFamilyName(const InternString& familyName) {
-		mFamilyName = familyName;
-	}
-	inline const InternString& IComponentFactory::getFamilyName() const {
-		return mFamilyName;
-	}
-
 	typedef boost::shared_ptr<IComponentFactory> ComponentFactoryPtr;
 
 
 	public:
 		virtual Component* create(Entity entity, const StringVariantMap& values) const {
 			Component* component = new T();
-
 			component->initialize(entity, values);
 
 			return component;

PolyMain/include/game/PolyComponentManager.cpp

 		itr = mFactories.find(typeName);
 
 		if(itr != mFactories.end()) {
+			// TODO don't copy values here, slow.
+			StringVariantMap componentValues = values.get(typeName, StringVariantMap());
+
 			ComponentFactoryPtr factory = (*itr).second;
 
-			Component* component = factory->create(entity, values);
+			Component* component = factory->create(entity, componentValues);
 			POLY_ASSERT(component);
 
 			return component;

PolyMain/include/game/PolyComponentManager.h

 
 								ComponentManager();
 
-		void					addComponentType(	const String& typeName,
-													ComponentFactoryPtr factory);
-
-		void					removeAllFactories();
+		void					addComponentType(const String& typeName, ComponentFactoryPtr factory);
 
 		template<typename ComponentType>
 		void					addComponentType();
 
+		void					removeAllFactories();
+
 		Component*				createComponent(Entity entity, 
 												const String& typeName, 
 												const StringVariantMap& values);
 	template<typename ComponentType>
 	inline void ComponentManager::addComponentType() {
 		ComponentFactoryPtr factory(new DefaultComponentFactory<ComponentType>());
-		factory->setFamilyName(ComponentType::GetFamilyName());
 
-		addComponentType(ComponentType::GetTypeName(), factory);
+		addComponentType(ComponentType::GetTypeInfo().name, factory);
 	}
 }
 

PolyMain/include/game/PolyEntity.cpp

 	TagSet Entity::msAllTags;
 	Entity::TagEntitiesMap Entity::msEntitiesByTag;
 	Entity::ComponentTypeEntitiesMap Entity::msEntitiesByComponentType;
-	Entity::TypeNameComponentMap Entity::msComponentsByFamily[(EntityID)-1];
+	Entity::TypeNameComponentMap Entity::msComponents[(EntityID)-1];
 
 	void Entity::addTag(const String& _tag) {
 		InternString tag(_tag);
 			return Entity();
 	}
 
-	Component* Entity::getComponent(const String& familyName, bool _throw) const {
+	Component* Entity::getComponent(const String& typeName, bool _throw) const {
 		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
 
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
+		TypeNameComponentMap& components = msComponents[mID];
 		TypeNameComponentMap::const_iterator itr;
 
-		itr = components.find(InternString(familyName));
+		itr = components.find(InternString(typeName));
 
 		if(itr != components.end()) {
 			return itr->second;
 		}
 		else if(_throw) {
 			POLY_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
-				"Component '" + familyName + "' not found in Entity!",
+				"Component '" + typeName + "' not found in Entity!",
 				"Entity::getComponent");
 		}
 
 
 		Component* newComponent = gEnv.componentMgr->createComponent(*this, typeName, values);
 
-		addComponent(newComponent);
+		addComponent(InternString(typeName), newComponent);
 	}
 
-	void Entity::addComponent(Component* component) {
+	void Entity::addComponent(const InternString& typeName, Component* component) {
 		POLY_ASSERT(component);
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
+		TypeNameComponentMap& components = msComponents[mID];
 
 		// Notify other components of this one
 		BOOST_FOREACH(TypeNameComponentMap::value_type pair, components)
 		BOOST_FOREACH(TypeNameComponentMap::value_type pair, components)
 			component->_notifyOtherComponentAdded(pair.second);
 
-		const InternString& familyName = component->getFamilyName();
-
-		components[familyName] = component;
-		msEntitiesByComponentType[familyName].insert(*this);
+		components[typeName] = component;
+		msEntitiesByComponentType[typeName].insert(*this);
 	}
 
 	void Entity::destroyComponent(Component* component) {
 		POLY_ASSERT(isValid());
 		POLY_ASSERT(component->getEntity() == *this);
 
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
+		TypeNameComponentMap& components = msComponents[mID];
 
 		// Notify other components of this one
 		BOOST_FOREACH(TypeNameComponentMap::value_type pair, components) {
 		}
 
 		// Remove component
-		const InternString& familyName = component->getFamilyName();
+		const InternString& typeName = InternString(component->getRuntimeTypeInfo().name);
 
 		{
 			TypeNameComponentMap::iterator itr;
-			itr = components.find(familyName);
+			itr = components.find(typeName);
 
 			if(itr != components.end())
 				components.erase(itr);
 
 		{
 			EntitySet::iterator itr;
-			itr = msEntitiesByComponentType[familyName].find(*this);
+			itr = msEntitiesByComponentType[typeName].find(*this);
 
-			if(itr != msEntitiesByComponentType[familyName].end())
-				msEntitiesByComponentType[familyName].erase(itr);
+			if(itr != msEntitiesByComponentType[typeName].end())
+				msEntitiesByComponentType[typeName].erase(itr);
 		}
 
 		POLY_DELETE(component);
 	void Entity::_destroyAllComponents() {
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
+		TypeNameComponentMap& components = msComponents[mID];
 
 		TypeNameComponentMap::iterator itr;
 		for(itr = components.begin(); itr != components.end();) {

PolyMain/include/game/PolyEntity.h

 		// Components
 		template<typename ComponentType>
 		bool						hasComponent() const;
-		bool						hasComponent(const String& familyName) const;
-		bool						hasComponent(const InternString& familyName) const;
+		bool						hasComponent(const String& typeName) const;
+		bool						hasComponent(const InternString& typeName) const;
 
 		/** Get Component by family name.
 		*/
 		static const EntitySet&		getWithComponent(const String& typeName);
 
 		void						createComponent(const String& typeName, const StringVariantMap& values=StringVariantMap());
-		void						addComponent(Component* component);
+		void						addComponent(const InternString& typeName, Component* component);
 		void						destroyComponent(Component* component);
 		void						_destroyAllComponents();
 
 		typedef map<InternString, EntitySet>::type ComponentTypeEntitiesMap;
 		static ComponentTypeEntitiesMap msEntitiesByComponentType;
 
-		static TypeNameComponentMap	msComponentsByFamily[(EntityID)-1];
+		static TypeNameComponentMap	msComponents[(EntityID)-1];
 	};
 
 	inline Entity::Entity()
 
 	template<typename ComponentType>
 	bool Entity::hasComponent() const {
+		return hasComponent(ComponentType::GetTypeInfo().name);
+	}
+
+	inline bool Entity::hasComponent(const String& typeName) const {
+		return hasComponent(InternString(typeName));
+	}
+
+	inline bool Entity::hasComponent(const InternString& typeName) const {
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
+		TypeNameComponentMap& components = msComponents[mID];
 		TypeNameComponentMap::const_iterator itr;
 
-		const InternString& familyName = ComponentType::GetFamilyName();
-		itr = components.find(familyName);
-
-		return itr != components.end();
-	}
-
-	inline bool Entity::hasComponent(const String& familyName) const {
-		return hasComponent(InternString(familyName));
-	}
-
-	inline bool Entity::hasComponent(const InternString& familyName) const {
-		POLY_ASSERT(isValid());
-
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
-		TypeNameComponentMap::const_iterator itr;
-
-		itr = components.find(InternString(familyName));
+		itr = components.find(typeName);
 
 		return itr != components.end();
 	}
 	ComponentType* Entity::getComponent(bool _throw) const {
 		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
 
-		TypeNameComponentMap& components = msComponentsByFamily[mID];
+		TypeNameComponentMap& components = msComponents[mID];
 		TypeNameComponentMap::const_iterator itr;
 
-		const InternString& familyName = ComponentType::GetFamilyName();
-		itr = components.find(familyName);
+		// Compile error here? You forgot the POLY_CLASS macro.
+		const String& typeName = ComponentType::GetTypeInfo().name;
+		itr = components.find(InternString(typeName));
 
 		if(itr != components.end()) {
-			// TODO don't want a dynamic_cast here, too slow.
-			return dynamic_cast<ComponentType*>(itr->second);
+			return static_cast<ComponentType*>(itr->second);
 		}
 		else if(_throw) {
 			POLY_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
-				"Component '" + familyName.get() + "' not found in Entity!",
+				"Component '" + typeName + "' not found in Entity!",
 				"Entity::getComponent");
 		}
 
 
 	inline const Entity::TypeNameComponentMap&	Entity::getComponents() const {
 		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
-		return msComponentsByFamily[mID];
+		return msComponents[mID];
 	}
 
 	inline const InternString& Entity::getTypeName() const {

PolyMain/include/game/PolyEntityManager.cpp

 			EntityTemplate entTemplate = itr->second;
 
 			StringVariantMap properties = _properties;
-			properties.defaults(entTemplate.getProperties());
+			properties.defaults(entTemplate.properties);
 
-			BOOST_FOREACH(const InternString& componentName, entTemplate.getComponents()) {
+			BOOST_FOREACH(const InternString& componentName, entTemplate.components) {
 				Component* component;
 				component = gEnv.componentMgr->createComponent(entity, componentName, properties);
 
-				entity.addComponent(component);
+				entity.addComponent(componentName, component);
 			}
 
 			mEntitiesToBeAdded.push_back(entity);

PolyMain/include/game/PolyEntityTemplate.h

 	/**
 	@ingroup Game
 	*/
-	class EntityTemplate {
+	struct EntityTemplate {
 	public:
-		void addComponent(const String& name);
-		const ComponentNameSet& getComponents() const { return mComponents; }
-
-		template<typename T>
-		void setProperty(const String& key, const T& val) {
-			mProperties[key] = val;
-		}
-
-		const StringVariantMap& getProperties() const { return mProperties; }
-
-	private:
-		ComponentNameSet mComponents;
-		StringVariantMap mProperties;
+		ComponentNameSet components;
+		StringVariantMap properties;
 	};
-
-	inline void EntityTemplate::addComponent(const String& name) {
-		mComponents.insert(InternString(name));
-	}
 }
 
 #endif

PolyMain/include/game/PolyEntityTemplateTranslator.cpp

 				String val;
 				
 				if(parseProperty(compiler, child, name, val)) {
-					entityTmpl.setProperty(name, val);
+					entityTmpl.properties[name] = val;
 				}
 			}
 			else if(child->type == Ogre::ANT_OBJECT) { // Component
 				Ogre::ObjectAbstractNode* componentNode = reinterpret_cast<Ogre::ObjectAbstractNode*>(child.get());
 
 				if(componentNode->cls == "component") {
-					entityTmpl.addComponent(componentNode->name);
+					entityTmpl.components.insert(InternString(componentNode->name));
+
+					StringVariantMap componentProps;
 
 					BOOST_FOREACH(Ogre::AbstractNodePtr componentChild, componentNode->children) {
 						if(componentChild->type == Ogre::ANT_PROPERTY) {
 							String val;
 
 							if(parseProperty(compiler, componentChild, name, val)) {
-								entityTmpl.setProperty(componentNode->name + "/" + name, val);
+								componentProps[name] = val;
 							}
 						}
 					}
+
+					entityTmpl.properties[componentNode->name] = componentProps;
 				}
 			}
 		}

PolyMain/include/game/PolyLightComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(LightComponent, "Light", "Light");
+	POLY_CLASS_IMPL(LightComponent,);
 
 	LightComponent::LightComponent() {
 		mProperties.addProperty("Light/Type", (String*)POLY_NULLPTR);
 	}
 
 	void LightComponent::_notifyOtherComponentAdded(Component* other) {
-		if(other->getFamilyName() != TransformComponent::GetFamilyName())
+		if(other->getRuntimeTypeInfo().name != TransformComponent::GetTypeInfo().name)
 			return;
 		if(sceneNode)
 			return;

PolyMain/include/game/PolyLightComponent.h

 		// Notifications
 		virtual void		_notifyOtherComponentAdded(Component* other);
 
-							POLY_COMPONENT_BASE;
+		POLY_CLASS;
 	};
 }
 

PolyMain/include/game/PolyMeshColliderComponent.cpp

 #include "render/PolyRenderUtil.h"
 #include "physics/PolyPhysicsSystem.h"
 #include "PolyPhysicsComponent.h"
+#include "PolyPhysicsDynamicComponent.h"
+#include "PolyPhysicsStaticComponent.h"
 
 #include "PolyMeshColliderComponent.h"
 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(MeshColliderComponent, "MeshCollider", "MeshCollider");
+	POLY_CLASS_IMPL(MeshColliderComponent,);
 
 	MeshColliderComponent::MeshColliderComponent() 
 	:	mOffset(Vector3::ZERO) {
-		mProperties.addProperty("MeshCollider/MeshName", &mMeshName);
-		mProperties.addProperty("MeshCollider/Offset", &mOffset, true);
+		mProperties.addProperty("MeshName", &mMeshName);
+		mProperties.addProperty("Offset", &mOffset, true);
 	}
 
 	void MeshColliderComponent::_notifyOtherComponentAdded(Component* other) {
-		if(other->getFamilyName() != PhysicsComponent::GetFamilyName())
+		// TODO fixme
+		if(other->getRuntimeTypeInfo().name != PhysicsStaticComponent::GetTypeInfo().name
+			|| other->getRuntimeTypeInfo().name != PhysicsDynamicComponent::GetTypeInfo().name)
 			return;
 
 		// Cook mesh

PolyMain/include/game/PolyMeshColliderComponent.h

 namespace Poly {
 	class _PolyExport MeshColliderComponent : public Component {
 	public:
-		MeshColliderComponent();
+						MeshColliderComponent();
 
-		virtual void _notifyOtherComponentAdded(Component* other);
+		virtual void	_notifyOtherComponentAdded(Component* other);
 
-		POLY_COMPONENT_BASE;
+		POLY_CLASS;
 
 	protected:
-		String mMeshName;
-		Vector3 mOffset;
+		String			mMeshName;
+		Vector3			mOffset;
 	};
 }
 

PolyMain/include/game/PolyMeshComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(MeshComponent, "Mesh", "Mesh");
+	POLY_CLASS_IMPL(MeshComponent,);
 
 	MeshComponent::MeshComponent()
 	:	sceneNode(POLY_NULLPTR),
 		mVisible(true),
 		mRenderQueueGroupID(Ogre::RENDER_QUEUE_MAIN) {
-		mProperties.addProperty("Mesh/Name", &mMeshName);
-		mProperties.addProperty("Mesh/Visible", &mVisible, true);
-		mProperties.addProperty("Mesh/RenderQueue", &mRenderQueueGroupID, true);
-		mProperties.addProperty("Mesh/MaterialName", &mMaterialName, true);
-		mProperties.addProperty("Mesh/CastShadows", (int*)POLY_NULLPTR, true);
+		mProperties.addProperty("Name", &mMeshName);
+		mProperties.addProperty("Visible", &mVisible, true);
+		mProperties.addProperty("RenderQueue", &mRenderQueueGroupID, true);
+		mProperties.addProperty("MaterialName", &mMaterialName, true);
+		mProperties.addProperty("CastShadows", (int*)POLY_NULLPTR, true);
 	}
 
 	MeshComponent::~MeshComponent() {
 	}
 
 	void MeshComponent::_notifyOtherComponentAdded(Component* other) {
-		if(other->getFamilyName() != TransformComponent::GetFamilyName())
+		if(other->getRuntimeTypeInfo().name != TransformComponent::GetTypeInfo().name)
 			return;
 		if(sceneNode)
 			return;

PolyMain/include/game/PolyMeshComponent.h

 		// Serialization
 		virtual void			serialize(StringVariantMap& params) const;
 
-								POLY_COMPONENT_BASE;
+		POLY_CLASS;
 
 	protected:
 		String					mMeshName;

PolyMain/include/game/PolyPhysicsComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(PhysicsComponent, "Physics", "Physics");
-
 	PhysicsComponent::PhysicsComponent() {
 	}
 }

PolyMain/include/game/PolyPhysicsComponent.h

 		void					setOrientation(const Quaternion& q);
 		Quaternion				getOrientation() const;
 
-								POLY_COMPONENT_BASE;
-
 	protected:
 								PhysicsComponent();
 	};

PolyMain/include/game/PolyPhysicsDynamicComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_CHILD_IMPL(PhysicsDynamicComponent, "PhysicsDynamic");
+	POLY_CLASS_IMPL(PhysicsDynamicComponent,);
 
 	PhysicsDynamicComponent::PhysicsDynamicComponent()
 	:	mKinematic(false) {
-		mProperties.addProperty("PhysicsDynamic/Kinematic", &mKinematic, true);
+		mProperties.addProperty("Kinematic", &mKinematic, true);
 	}
 
 	PhysicsDynamicComponent::~PhysicsDynamicComponent() {

PolyMain/include/game/PolyPhysicsDynamicComponent.h

 		void					setKinetic(bool val);
 		bool					isKinematic() const;
 
-								POLY_COMPONENT_CHILD;
+		POLY_CLASS;
 
 	protected:
 		bool					mKinematic;

PolyMain/include/game/PolyPhysicsStaticComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_CHILD_IMPL(PhysicsStaticComponent, "PhysicsStatic");
+	POLY_CLASS_IMPL(PhysicsStaticComponent,);
 
 	PhysicsStaticComponent::PhysicsStaticComponent() {
 	}

PolyMain/include/game/PolyPhysicsStaticComponent.h

 		
 		virtual void			initialize(Entity entity, const StringVariantMap& values);
 
-								POLY_COMPONENT_CHILD;
+		POLY_CLASS;
 	};
 }
 

PolyMain/include/game/PolyTransformComponent.cpp

 
 
 namespace Poly {
-	POLY_COMPONENT_BASE_IMPL(TransformComponent, "Transform", "Transform");
+	POLY_CLASS_IMPL(TransformComponent,);
 
 	TransformComponent::TransformComponent() {
-		mProperties.addProperty("Transform/Position", (Vector3*)POLY_NULLPTR, true);
-		mProperties.addProperty("Transform/Orientation", (Quaternion*)POLY_NULLPTR, true);
-		mProperties.addProperty("Transform/Scale", (Vector3*)POLY_NULLPTR, true);
+		mProperties.addProperty("Position", (Vector3*)POLY_NULLPTR, true);
+		mProperties.addProperty("Orientation", (Quaternion*)POLY_NULLPTR, true);
+		mProperties.addProperty("Scale", (Vector3*)POLY_NULLPTR, true);
 	}
 
 	TransformComponent::~TransformComponent() {

PolyMain/include/game/PolyTransformComponent.h

 		void					setParent(TransformComponent* other);
 		void					resetParent();
 
-								POLY_COMPONENT_BASE;
+		POLY_CLASS;
 	};
 }
 

PolyMain/include/util/PolyReflection.h

 		class TypeRepositoryEntry {
 		public:
 			TypeRepositoryEntry() {
-				TypeRepository::registerType(T::getTypeInfo());
+				TypeRepository::registerType(T::GetTypeInfo());
 			}
 		};
 	}
 
 #define POLY_CLASS \
 	virtual const ::Poly::RTTI::TypeInfo& getRuntimeTypeInfo() const; \
-	static const ::Poly::RTTI::TypeInfo& getTypeInfo()
+	static const ::Poly::RTTI::TypeInfo& GetTypeInfo()
 
 #define POLY_CLASS_IMPL(ClassType, Members) \
 	static ::Poly::RTTI::TypeRepositoryEntry<ClassType> ClassType##RepositoryEntry; \
 	 \
 	const ::Poly::RTTI::TypeInfo& ClassType::getRuntimeTypeInfo() const { \
-		return getTypeInfo(); \
+		return ClassType::GetTypeInfo(); \
 	} \
 	 \
-	const ::Poly::RTTI::TypeInfo& ClassType::getTypeInfo() { \
+	const ::Poly::RTTI::TypeInfo& ClassType::GetTypeInfo() { \
 		static ::Poly::RTTI::TypeInfo info; \
 		static bool infoGenerated = false; \
 		if(!infoGenerated) { \

PolyPython/include/PolyPython.h

 		*/
 		template<typename T>
 		void addNativeComponentType() {
-			NativeComponentToPythonPtr converter(new NativeComponentToPythonImpl<T>());
-			gNativeComponentToPythonConverters.insert(std::make_pair(T::GetFamilyName(), converter));
+			InternString typeName = InternString(T::GetTypeInfo().name);
+
+			NameConverterMap::iterator itr;
+			itr = gNativeComponentToPythonConverters.find(typeName);
+
+			if(itr == gNativeComponentToPythonConverters.end()) {
+				NativeComponentToPythonPtr converter(new NativeComponentToPythonImpl<T>());
+
+				gNativeComponentToPythonConverters.insert(std::make_pair(typeName, converter));
+
+				//POLY_LOG_TRIVIAL("Native ComponentType for type '" << T::GetTypeInfo().name << "' registered");
+			}
+			else {
+				POLY_LOG_CRITICAL("Registered native ComponentType '" << T::GetTypeInfo().name << "' twice!");
+			}
 		}
 
 		bool isNativeComponentType(const String& str);

PolyPython/include/PolyPythonBindings.cpp

 	bindPhysics();
 
 	// Runtime environment
+	ComponentManager* componentMgr =  gEnv.componentMgr.get();
+	bp::scope().attr("componentMgr") = boost::ref(componentMgr); 
+
 	EntityManager* entityMgr =  gEnv.entityMgr.get();
 	bp::scope().attr("entityMgr") = boost::ref(entityMgr); 
 

PolyPython/include/PolyPythonGameBindings.h

 		self.GameState::startup();
 	}
 
-private:
+protected:
 	PyObject* mSelf;
 };
 
+class PythonComponent : public Component {
+public:
+	bp::object instance;
+
+	PythonComponent(PyObject* p)
+	:	mSelf(p) {}
+	PythonComponent(PyObject* p, const Component& self)
+	:	mSelf(p) {}
+
+protected:
+	PyObject* mSelf;
+};
+
+class PythonComponentFactory : public IComponentFactory {
+public:
+	PythonComponentFactory(bp::object componentType)
+	:	mComponentType(componentType) {
+	}
+
+	virtual Component* create(Entity entity, const StringVariantMap& values) const {
+		try {
+			bp::object instance = mComponentType.attr("__call__")();
+			PythonComponent* pc = bp::extract<PythonComponent*>(instance);
+			pc->instance = instance;
+
+			return pc;
+		}
+		catch(const bp::error_already_set&) {
+			Poly::Python::_fetchError();
+
+			return POLY_NULLPTR;
+		}
+	}
+
+protected:
+	bp::object mComponentType;
+};
+
 bp::object Entity_GetComponent(Entity& self, const String& typeName) {
-	bp::object ret;
+	if(!self.hasComponent(typeName))
+		return bp::object();
+
+	Component* component = self.getComponent(typeName);
 
 	if(Poly::Python::isNativeComponentType(typeName)) {
-		Component* component = self.getComponent(typeName);
-
 		return Poly::Python::convertNativeComponentToPython(typeName, component);
 	}
 	else {
-		// TODO
+		PythonComponent* pc = dynamic_cast<PythonComponent*>(component);
+		if(!pc)
+			return bp::object();
 
-		return bp::object();
+		return pc->instance;
 	}
 }
 
 	return self.createLevel();
 }
 
+void ComponentManager_addComponentType(ComponentManager& self, bp::object componentType) {
+	String typeName = bp::extract<String>(componentType.attr("__name__"));
+	
+	ComponentFactoryPtr factory(new PythonComponentFactory(componentType));
+	
+	self.addComponentType(typeName, factory);
+}
+
 Entity EntityManager_createEntity(EntityManager& self, Level level, const String& typeName) {
 	StringVariantMap _props;
 
 }
 
 void bindGame() {
+	// Level
 	bp::class_<Level>("Level", bp::no_init);
 
 	bp::class_<LevelManager, boost::noncopyable>("LevelManager", bp::no_init)
 		.def("createLevel", &LevelManager_createLevel);
 
 	// Component
-	bp::class_<Component, boost::noncopyable>("Component", bp::no_init);
+	bp::class_<ComponentManager, boost::noncopyable>("ComponentManager", bp::no_init)
+		.def("addComponentType", &ComponentManager_addComponentType);
 
-	bp::class_<TransformComponent, bp::bases<Component>>("Transform")
+	bp::class_<Component, PythonComponent, boost::noncopyable>("Component", bp::init<>());
+
+	bp::class_<TransformComponent, bp::bases<Component>>("TransformComponent")
 		.add_property("sceneNode", bp::make_getter(&TransformComponent::sceneNode, bp::return_internal_reference<>()));
 
 	// Entity