Sirikata
|
00001 // Copyright (c) 2011 Sirikata Authors. All rights reserved. 00002 // Use of this source code is governed by a BSD-style license that can 00003 // be found in the LICENSE file. 00004 00005 #ifndef _SIRIKATA_JS_VISIBLE_DATA_HPP_ 00006 #define _SIRIKATA_JS_VISIBLE_DATA_HPP_ 00007 00008 #include <sirikata/core/util/Platform.hpp> 00009 #include <sirikata/core/util/PresenceProperties.hpp> 00010 #include <sirikata/proxyobject/ProxyObject.hpp> 00011 00012 namespace Sirikata{ 00013 namespace JS{ 00014 00015 class JSVisibleStruct; 00016 00017 class JSVisibleData; 00018 typedef std::tr1::weak_ptr<JSVisibleData> JSVisibleDataWPtr; 00019 typedef std::tr1::shared_ptr<JSVisibleData> JSVisibleDataPtr; 00020 00022 class JSVisibleDataListener { 00023 public: 00024 virtual ~JSVisibleDataListener() {} 00025 00026 virtual void removeVisibleData(JSVisibleData* data) = 0; 00027 }; 00028 00042 class JSVisibleData : public virtual IPresencePropertiesRead { 00043 public: 00044 JSVisibleData(JSVisibleDataListener* parent) 00045 : mParent(parent) 00046 {} 00047 ~JSVisibleData(); 00048 00050 virtual const SpaceObjectReference& id() = 0; 00052 virtual const SpaceObjectReference& observer() = 0; 00053 00054 // "Disables" this data, making it invalid. Only used when we know 00055 // its safe to destroy everything because the script is being 00056 // killed. Also ensures we are able to clean up since references 00057 // to proxies, which hold references to the parent object, are 00058 // cleared by this. 00059 virtual void disable(); 00060 protected: 00061 // Clear the data for this visible (i.e. for the ID given) from the parent script. 00062 void clearFromParent(); 00063 00064 JSVisibleDataListener* mParent; 00065 }; 00066 00067 class JSRestoredVisibleData; 00068 typedef std::tr1::shared_ptr<JSRestoredVisibleData> JSRestoredVisibleDataPtr; 00070 class JSRestoredVisibleData : public JSVisibleData, public PresenceProperties { 00071 public: 00072 // Regular constructors representing real data (although possibly from 00073 // restored data, i.e. not valid according to the space). 00074 JSRestoredVisibleData(JSVisibleDataListener* parent, const SpaceObjectReference& from, JSVisibleDataPtr fromData = JSVisibleDataPtr()); 00075 JSRestoredVisibleData(JSVisibleDataListener* parent, const SpaceObjectReference& from, const IPresencePropertiesRead& orig); 00076 00077 virtual ~JSRestoredVisibleData(); 00078 00079 virtual const SpaceObjectReference& id(); 00080 virtual const SpaceObjectReference& observer(); 00081 00082 // IPresencePropertiesRead Interface is implemented by PresenceProperties 00083 00084 void updateFrom(const IPresencePropertiesRead& orig); 00085 private: 00086 SpaceObjectReference sporefToListenTo; 00087 00088 JSRestoredVisibleData(); 00089 }; 00090 00091 00093 class JSProxyVisibleData : public JSVisibleData { 00094 public: 00095 JSProxyVisibleData(JSVisibleDataListener* parent, ProxyObjectPtr from); 00096 virtual ~JSProxyVisibleData(); 00097 00098 virtual const SpaceObjectReference& id(); 00099 virtual const SpaceObjectReference& observer(); 00100 00101 virtual void disable(); 00102 00103 // IPresencePropertiesRead Interface 00104 virtual TimedMotionVector3f location() const { return proxy->location(); } 00105 virtual TimedMotionQuaternion orientation() const { return proxy->orientation(); } 00106 virtual AggregateBoundingInfo bounds() const { return proxy->bounds(); } 00107 virtual Transfer::URI mesh() const { return proxy->mesh(); } 00108 virtual String physics() const { return proxy->physics(); } 00109 virtual bool isAggregate() const { return proxy->isAggregate(); } 00110 virtual ObjectReference parent() const { return proxy->parentAggregate(); } 00111 00112 private: 00113 JSProxyVisibleData(); 00114 00115 ProxyObjectPtr proxy; 00116 }; 00117 00118 00119 00120 class JSAggregateVisibleData; 00121 typedef std::tr1::shared_ptr<JSAggregateVisibleData> JSAggregateVisibleDataPtr; 00122 typedef std::tr1::weak_ptr<JSAggregateVisibleData> JSAggregateVisibleDataWPtr; 00126 class JSAggregateVisibleData : 00127 public JSVisibleData, 00128 public JSVisibleDataListener, 00129 Noncopyable 00130 { 00131 public: 00132 // Construct aggregate, starting with an ID (e.g. when we've received a 00133 // message) and possibly some restored data (e.g. when we're restoring). 00134 JSAggregateVisibleData(JSVisibleDataListener* parent, const SpaceObjectReference& vis); 00135 virtual ~JSAggregateVisibleData(); 00136 00137 virtual const SpaceObjectReference& id(); 00138 virtual const SpaceObjectReference& observer(); 00139 00140 virtual void disable(); 00141 00142 // Indicates whether this presence is visible to a presence or not, i.e. if 00143 // any ProxyObject still exists for it. 00144 bool visibleToPresence() const; 00145 00146 // IPresencePropertiesRead Interface 00147 virtual TimedMotionVector3f location() const; 00148 virtual TimedMotionQuaternion orientation() const; 00149 virtual AggregateBoundingInfo bounds() const; 00150 virtual Transfer::URI mesh() const; 00151 virtual String physics() const; 00152 virtual bool isAggregate() const; 00153 virtual ObjectReference parent() const; 00154 00155 // JSVisibleDataListener 00156 virtual void removeVisibleData(JSVisibleData* data); 00157 00158 void updateFrom(ProxyObjectPtr proxy); 00159 void updateFrom(const IPresencePropertiesRead& props); 00160 00161 // Called for *ProxyObject* references. 00162 void incref(JSVisibleDataPtr self); 00163 void decref(); 00164 00165 private: 00166 JSAggregateVisibleData(); 00167 00168 JSVisibleDataPtr getBestChild() const; 00169 00170 // Number of references to this JSVisibleData *by ProxyObjectPtrs* 00171 // (not by v8 objects). We use a slightly confusing setup to 00172 // manage the lifetime of the object. The refcount forces this 00173 // object to maintain a shared_ptr to itself, guaranteeing it'll 00174 // stay alive. For each v8 visible, there is also a shared_ptr. 00175 int32 refcount; 00176 JSVisibleDataPtr selfPtr; 00177 00178 // Within an aggregate, all IDs should be the same. We index by the owning 00179 // presence of each individual Visible. 00180 // TODO(ewencp) These have to be strong references since nothing else will 00181 // hold on to them, but then they will just continue to aggregate unless we 00182 // have some way of turning them weak + maintaining the latest updated child 00183 // as a strong ref. 00184 typedef std::map<SpaceObjectReference, JSVisibleDataPtr> ChildMap; 00185 ChildMap mChildren; 00186 SpaceObjectReference mBest; 00187 00188 typedef boost::mutex Mutex; 00189 Mutex childMutex; 00190 00191 00192 }; 00193 00194 } // namespace JS 00195 } // namespace Sirikata 00196 00197 #endif // _SIRIKATA_JS_VISIBLE_DATA_HPP_