Sirikata
liboh/plugins/js/JSVisibleData.hpp
Go to the documentation of this file.
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_