Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

Entity.h

00001 #ifndef ERIS_ENTITY_H 00002 #define ERIS_ENTITY_H 00003 00004 // local headers 00005 #include <Eris/SignalDispatcher.h> 00006 #include <Eris/Types.h> 00007 00008 #include <Atlas/Message/Element.h> 00009 00010 #include <wfmath/point.h> 00011 #include <wfmath/vector.h> 00012 #include <wfmath/axisbox.h> 00013 #include <wfmath/quaternion.h> 00014 00015 namespace Atlas { 00016 namespace Objects { 00017 namespace Entity { 00018 class RootEntity; 00019 class GameEntity; 00020 } 00021 00022 namespace Operation { 00023 class Move; 00024 class Set; 00025 class Sound; 00026 class Talk; 00027 } 00028 } 00029 } 00030 00031 00032 namespace Eris { 00033 00034 // Forward Declerations 00035 class Entity; 00036 class World; 00037 class Dispatcher; 00038 class Property; 00039 class TypeInfo; 00040 00041 typedef std::vector<Entity*> EntityArray; 00042 00043 typedef std::map<std::string, Property*> PropertyMap; 00044 00046 00056 class Entity : virtual public SigC::Object 00057 { 00058 public: 00059 explicit Entity(const Atlas::Objects::Entity::GameEntity &ge, World *world); 00060 virtual ~Entity(); 00061 00062 /* container interface; not virtualized, should it be? i.e, will anyone want to 00063 change containership semantics on the client? Assume no until proved 00064 otherwise */ 00065 Entity* getContainer() const 00066 { return _container; } 00067 00068 unsigned int getNumMembers() const 00069 { return _members.size(); } 00070 00071 bool hasBBox() const 00072 { return _hasBBox; } 00073 00074 Entity* getMember(unsigned int index); 00075 00076 // property query interface 00078 virtual const Atlas::Message::Element& getProperty(const std::string &p) const; 00080 virtual bool hasProperty(const std::string &p) const; 00081 00082 // dynamics; these are virtual to allow derived class to implement motion 00083 // prediction or other effects that can't be guessed here 00084 virtual WFMath::Point<3> getPosition() const; 00085 virtual WFMath::Vector<3> getVelocity() const; 00086 00088 virtual WFMath::Quaternion getOrientation() const; 00089 00090 virtual WFMath::AxisBox<3> getBBox() const; 00091 00092 // accesors 00094 const std::string& getID() const { return _id;} 00095 const std::string& getName() const { return _name;} 00096 00098 float getStamp() const 00099 { return _stamp; } 00100 00102 StringSet getInherits() const 00103 { return _parents; } 00104 00105 TypeInfo* getType() const; 00106 00107 World* getWorld() const 00108 { return _world; } 00109 00112 bool isVisible() const 00113 { return _visible; } 00114 00115 // coordinate transformations 00116 template<class C> C toParentCoords(const C& c) const 00117 {return c.toParentCoords(_position, _orientation);} 00118 template<class C> C fromParentCoords(const C& c) const 00119 {return c.toLocalCoords(_position, _orientation);} 00120 // A vector (e.g., the distance between two points, or 00121 // a velocity) gets rotated by a coordinate transformation, 00122 // but doesn't get shifted by the change in the position 00123 // of the origin, so we handle it separately. We also 00124 // need to copy the vector before rotating, because 00125 // Vector::rotate() rotates it in place. 00126 WFMath::Vector<3> toParentCoords(const WFMath::Vector<3>& v) const 00127 {return WFMath::Vector<3>(v).rotate(_orientation);} 00128 WFMath::Vector<3> fromParentCoords(const WFMath::Vector<3>& v) const 00129 {return WFMath::Vector<3>(v).rotate(_orientation.inverse());} 00130 00131 // Signals 00132 SigC::Signal1<void, Entity*> AddedMember; 00133 SigC::Signal1<void, Entity*> RemovedMember; 00134 00136 00140 SigC::Signal2<void, Entity*, Entity*> Recontainered; 00141 00143 SigC::Signal1<void, const StringSet&> Changed; 00144 00147 SigC::Signal1<void, const WFMath::Point<3>&> Moved; 00148 00150 SigC::Signal1<void, const std::string&> Say; 00151 00154 template <class T> 00155 void connectOpToSlot(const std::string &op, const SigC::Slot1<void, const T&> &slot) 00156 { innerOpToSlot(new SignalDispatcher<T>(op, slot)); } 00157 00160 template <class T> 00161 void connectOpFromSlot(const std::string &op, SigC::Slot1<void, const T&> &slot) 00162 { innerOpFromSlot(new SignalDispatcher<T>(op, slot)); } 00163 00164 void observeProperty(const std::string &nm, 00165 const SigC::Slot1<void, const Atlas::Message::Element&> slot); 00166 00167 protected: 00169 explicit Entity(const std::string &id, World *world); 00170 00171 // the World is a friend, so that it may set properties and containership of 00172 // entities. 00173 friend class World; 00174 00175 virtual void handleMove(); 00176 virtual void handleTalk(const std::string &msg); 00177 00179 virtual void setProperty(const std::string &p, const Atlas::Message::Element &v); 00180 00181 virtual void setPosition(const WFMath::Point<3>& pt); 00183 virtual void setContainer(Entity *pr); 00184 00185 virtual void setContents(const Atlas::Message::Element::ListType &contents); 00186 00188 virtual void addMember(Entity *e); 00189 00191 00193 virtual void rmvMember(Entity *e); 00194 00198 virtual void setVisible(bool vis); 00199 00200 void setContainerById(const std::string &id); 00201 00202 const std::string _id; 00203 std::string _name; 00204 float _stamp; 00205 std::string _description;// surely this should be retrieved dynamically from the server? 00206 StringSet _parents; 00207 bool _visible; 00208 00209 // container-ship / entity heirarchy 00210 Entity* _container; 00211 EntityArray _members; 00212 00213 WFMath::AxisBox<3> _bbox; 00214 WFMath::Point<3> _position; 00215 WFMath::Vector<3> _velocity; 00216 WFMath::Quaternion _orientation; 00217 00218 // properties 00219 void beginUpdate(); 00220 void endUpdate(); 00221 00222 PropertyMap _properties; 00223 00227 bool _inUpdate; 00228 00232 bool _hasBBox; 00233 00238 StringSet _modified; 00239 00240 private: 00241 //friend class World; // World has to be a friend so it can call these 00242 00243 // these are private and final so sub-classing people don't get confused with the 00244 // respective handleXXXX methods. If you want to change how the raw Atlas 00245 // operation is processed, setup a custom dispatcher. 00246 void recvSight(const Atlas::Objects::Entity::GameEntity &ge); 00247 void recvMove(const Atlas::Objects::Operation::Move &mv); 00248 void recvSet(const Atlas::Objects::Operation::Set &st); 00249 00250 void recvSound(const Atlas::Objects::Operation::Sound &snd); 00251 void recvTalk(const Atlas::Objects::Operation::Talk &tk); 00252 00253 void innerOpFromSlot(Dispatcher *s); 00254 void innerOpToSlot(Dispatcher *s); 00255 00256 // disptchers that have been bound to this entity (so we know to delete them) 00257 StringList _localDispatchers; 00258 00259 World *_world; // the World that created the Entity 00260 }; 00261 00262 00263 // motion predicted entity that moves a lot. 00264 class Moveable : public Entity 00265 { 00266 typedef Entity Inherited; 00267 public: 00268 Moveable(const std::string &id); 00269 virtual ~Moveable(); 00270 00271 virtual WFMath::Point<3> getPosition() const {return Inherited::getPosition();} 00272 void getPosition(bool predicted); 00273 00274 protected: 00275 WFMath::Vector<3> _velocity, 00276 _delta; 00277 }; 00278 00279 } // of namespace 00280 00281 #endif

Generated on Tue Jul 27 21:00:43 2004 for Eris by doxygen 1.3.7