Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/metaobjects/property/propertylistener.hh

Go to the documentation of this file.
00001 /*
00002     This file is part of the Virtual Object System of
00003     the Interreality project (http://interreality.org).
00004 
00005     Copyright (C) 2001, 2002 Peter Amstutz
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020 
00021     Peter Amstutz <tetron@interreality.org>
00022     Additions by Reed Hedges <reed@zerohour.net> marked with initials "rh" and date.
00023 */
00024 #ifndef _PROPERTY_LISTENER_HH_
00025 #define _PROPERTY_LISTENER_HH_
00026 
00027 
00028 #include <vos/corelibs/vos/vos.hh>
00029 
00030 class Property;
00031 class ExtrapolatedProperty;
00032 
00033 /** @class PropertyEvent propertylistener.hh vos/metaobjects/property/propertylistener.hh
00034  *  PropertyEvents are passed to PropertyListener objectss to notify them of 
00035  *  changes to the properties they are listening to.
00036  */ 
00037 class PROPERTY_API PropertyEvent : public RefCounted
00038 {
00039 public:
00040     typedef enum {PropertyWrite, PropertyReplace, PropertyRead} EventType;  
00041 
00042 private:
00043     EventType event;
00044     string oldvalue;
00045     string newvalue;
00046     string olddatatype;
00047     string newdatatype;
00048     Vobject* initiator;
00049     Property* property;
00050     int offset;
00051     int length;
00052     bool isACcheck;
00053     
00054 public:
00055     PropertyEvent(EventType et, Vobject& init, Property& property,
00056                   const string& value, 
00057                   const string& datatype,
00058                   bool isACcheck);
00059     PropertyEvent(EventType et, Vobject& init, Property& property,
00060                   const string& value, 
00061                   const string& datatype, 
00062                   const string& oldvalue,
00063                   const string& olddatatype, 
00064                   bool isACcheck);
00065     PropertyEvent(EventType et, Vobject& init, Property& property, 
00066                   int offset, 
00067                   int length, 
00068                   const string& value,
00069                   const string& datatype,
00070                   bool isACcheck);
00071     PropertyEvent(EventType et, Vobject& init, Property& property, 
00072                   int offset, 
00073                   int length, 
00074                   const string& value,
00075                   const string& datatype,
00076                   const string& oldvalue,
00077                   const string& olddatatype,
00078                   bool isACcheck);
00079 
00080     virtual ~PropertyEvent();
00081 
00082     /** @return What type of event this is. */
00083     EventType getEvent() const { return event; }
00084 
00085     /** @return The object which requested or initiated this event.
00086         Always valid.  For access control checks, this is the object
00087         which is requesting access.  Note that unlike most parts of
00088         the API the reference count on the returned object is NOT
00089         increased (acquire is NOT called) so if you plan on keeping a
00090         reference to it past the lifetime of the callback, you must
00091         call acquire yourself!  This also means you should NOT assign
00092         the returned value to a vRef!
00093      */
00094     Vobject* getInitiator() const { return initiator; }
00095 
00096     /** @return The property which is being accessed or changed.
00097         Always valid.  For access control checks, this is the object
00098         which is requesting access.  Note that unlike most parts of
00099         the API the reference count on the returned object is NOT
00100         increased (acquire is NOT called) so if you plan on keeping a
00101         reference to it past the lifetime of the callback, you must
00102         call acquire yourself!  This also means you should NOT assign
00103         the returned value to a vRef!
00104      */
00105     Property* getProperty() const { return property; }
00106 
00107     /** @return The beginning of the changed section.  
00108         @note If you want to know what exactly section of the property
00109         changed on a write event, use
00110         @code
00111 string section = e.getNewValue().substr(e.getOffset(), e.getLength());
00112         @endcode
00113     */
00114     unsigned int getOffset() const { return offset; }
00115 
00116     /** @return The size of the changed section. */
00117     unsigned int getLength() const { return length; }
00118 
00119     /** @return The previous value of this property, prior to a
00120         proposed change (for access control checks) or prior to the
00121         most recent change (for notify events). */
00122     const string& getOldValue() const { return oldvalue; }
00123 
00124     /** @return For an access control check, this is the proposed new
00125         value (it has not been commited yet).  For a notify event, the
00126         new value for this property.  */
00127     const string& getNewValue() const { return newvalue; }
00128 
00129     /** @return For an access control check, this is the old property
00130         value (the change has not been commited yet).  For a notify
00131         event it is the current value of the property.  */
00132     const string& getValue() const 
00133         { return (isACcheck ? oldvalue : newvalue); }
00134 
00135     /** Only to be used for access control checks.  This allows you to
00136         modify the proposed new value for this property.  
00137         @param v the new value to use */
00138     void setNewValue(const string& v) { newvalue = v; }
00139 
00140     /** @return The previous datatype of this property, prior to a
00141         proposed change (for access control checks) or prior to the
00142         most recent change (for notify events). */
00143     const string& getOldDataType() const { return olddatatype; }
00144 
00145     /** @return For an access control check, this is the proposed new
00146         datatype (it has not been commited yet).  For a notify event, the
00147         new datatype for this property.  */
00148     const string& getNewDataType() const { return newdatatype; }
00149 
00150     /** @return For an access control check, this is the old property
00151         datatype (the change has not been commited yet).  For a notify
00152         event it is the current datatype of the property.  */
00153     const string& getDataType() const
00154         { return (isACcheck ? olddatatype : newdatatype); }
00155 
00156     /** Only to be used for access control checks.  This allows you to
00157         modify the proposed new datatype for this property.  
00158         @param dt the new datatype to use */
00159     void setNewDataType(const string& dt) { newdatatype = dt; }
00160 };
00161  
00162 /** @class PropertyEvent propertylistener.hh vos/metaobjects/property/propertylistener.hh
00163  *  PropertyListener objects will be notified of all changes to Properties
00164  *  to which they are listening. Create a subclass and override 
00165  *  notifyPropertyChanged, create an instance, and then use 
00166  *  Property::addPropertyListener to register your listener with that
00167  *  property.
00168  */
00169 class PROPERTY_API PropertyListener {
00170 public:
00171     virtual ~PropertyListener();
00172 
00173     /** Notification interface that a property has been changed.
00174      * Override this method in your subclass.
00175      *  @param event Event describing what happened. Note the 'const' declaration.
00176      */
00177     virtual void notifyPropertyChange(const PropertyEvent& event) = 0;
00178 };
00179 
00180 
00181 /** @class ExtrapolatedPropertyEvent propertylistener.hh vos/metaobjects/property/propertylistener.hh
00182  *  Listener for ExtrapolatedProperty changes.
00183  */
00184 class PROPERTY_API ExtrapolatedPropertyListener {
00185 public:
00186     virtual void notifyBaseChange(ExtrapolatedProperty& ep,
00187                                       const vector<double>& position,
00188                                       const vector<double>& velocity,
00189                                       const vector<double>& acceleration,
00190                                       double t) = 0;
00191     virtual void notifyPositionChange(ExtrapolatedProperty& ep,
00192                                       const vector<double>& position,
00193                                       const vector<double>& velocity,
00194                                       const vector<double>& acceleration,
00195                                       double t) = 0;
00196 };
00197 
00198 
00199 /** @class DoNothingPropertyEvent propertylistener.hh vos/metaobjects/property/propertylistener.hh
00200  *  This is a PropertyListener that does nothing; however, it can be used
00201  *  to keep a RemoteProperty up to date with changes in a LocalProperty,
00202  *  speeding up reads of the RemoteProperty.
00203  */
00204 class PROPERTY_API DoNothingPropertyListener : public virtual PropertyListener, public virtual ExtrapolatedPropertyListener
00205 {
00206 public:
00207     static DoNothingPropertyListener static_;
00208 
00209     virtual void notifyPropertyChange(const PropertyEvent& e) {};
00210 
00211     virtual void notifyPositionChange(ExtrapolatedProperty& , const vector<double>& , const vector<double>& ,
00212                                       const vector<double>& , double ) {};
00213     virtual void notifyBaseChange(ExtrapolatedProperty& , const vector<double>& , const vector<double>& ,
00214                                   const vector<double>& , double ) {};
00215 };
00216 
00217 
00218 
00219 /** Internal class used to sort of extend RemoteSite without actually
00220     touching RemoteSite.  Users don't need to worry about this.
00221     @internal
00222 */
00223 class ExtrapolatedListenerSiteWrapper : public virtual ExtrapolatedPropertyListener
00224 {
00225 public:
00226     Site* site;
00227     ExtrapolatedListenerSiteWrapper(Site* s);
00228     virtual ~ExtrapolatedListenerSiteWrapper();
00229     virtual void notifyPositionChange(ExtrapolatedProperty& ep,
00230                                       const vector<double>& position,
00231                                       const vector<double>& velocity,
00232                                       const vector<double>& acceleration,
00233                                       double t);
00234     virtual void notifyBaseChange(ExtrapolatedProperty& ep,
00235                                       const vector<double>& position,
00236                                       const vector<double>& velocity,
00237                                       const vector<double>& acceleration,
00238                                       double t);
00239     class Cmp {
00240     public:
00241         inline bool operator()(const ExtrapolatedPropertyListener* p, const ExtrapolatedPropertyListener* q) const {
00242             const ExtrapolatedListenerSiteWrapper* pw;
00243             const ExtrapolatedListenerSiteWrapper* qw;
00244             if((pw = dynamic_cast<const ExtrapolatedListenerSiteWrapper*>(p))
00245                && (qw = dynamic_cast<const ExtrapolatedListenerSiteWrapper*>(q)))
00246             {
00247                 return pw->site < qw->site;
00248             } else return (p < q);
00249         };
00250     };
00251 };
00252 
00253 
00254 /** Internal class used to sort of extend RemoteSite without actually
00255     touching RemoteSite.  Users don't need to worry about this.
00256     @internal
00257 */
00258 class PropertyListenerSiteWrapper : public virtual PropertyListener
00259 {
00260     string firstnonce;
00261 public:
00262     Site* site;
00263     PropertyListenerSiteWrapper(Site* s, const string& firstnonce);
00264     PropertyListenerSiteWrapper(Site* s);
00265     virtual ~PropertyListenerSiteWrapper();
00266     virtual void notifyPropertyChange(const PropertyEvent& e);
00267 
00268     class Cmp {
00269     public:
00270         inline bool operator()(const PropertyListener* p, const PropertyListener* q) const {
00271             const PropertyListenerSiteWrapper* pw;
00272             const PropertyListenerSiteWrapper* qw;
00273             if((pw = dynamic_cast<const PropertyListenerSiteWrapper*>(p))
00274                && (qw = dynamic_cast<const PropertyListenerSiteWrapper*>(q)))
00275             {
00276                 return pw->site < qw->site;
00277             } else return (p < q);
00278         };
00279     };
00280 };
00281 
00282 
00283 
00284 #endif

Generated on Tue Aug 12 03:55:46 2003 for Interreality Project - VOS by doxygen 1.3.2