Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | 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 Sun Sep 4 14:14:04 2005 for Eris by  doxygen 1.4.4