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

vos/corelibs/vos/vobject.hh

Go to the documentation of this file.
00001 /*
00002 
00003     This file is part of the Virtual Object System of
00004     the Interreality project (http://interreality.org).
00005 
00006     Copyright (C) 2001-2003 Peter Amstutz
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00021 
00022     Peter Amstutz <tetron@interreality.org>
00023 */
00024 
00025 #ifndef _VOBJECT_HH_
00026 #define _VOBJECT_HH_
00027 
00028 /** @file
00029     Defines Vobject and VobjectImplementation.
00030 */
00031 
00032 #include <vos/corelibs/vos/refcount.hh>
00033 #include <vos/corelibs/vos/url.hh> // Need this for the exception
00034 #include <vos/corelibs/vos/log.hh>
00035 
00036 #include <deque>
00037 #include <stdexcept>
00038 
00039 /** Virtual Object System core library */
00040 
00041 namespace VOS
00042 {
00043     class Site;
00044     class Message;
00045     class MessageBlock;
00046     class TypeChangeListener;
00047     class ParentChangeListener;
00048     class ChildChangeListener;
00049 
00050 /** @class Vobject vobject.hh vos/corelibs/vos/vobject.hh
00051  *
00052  * This is the abstract class that defines the basic API common to
00053     all virtual objects.
00054 */
00055 class VOS_API Vobject : public virtual RefCounted
00056 {
00057 public:
00058     /** This structure expresses the relation between a parent vobject
00059         and a vobject which is a child of that parent.
00060     */
00061     class ParentChildRelation : public virtual RefCounted
00062     {
00063     public:
00064         ParentChildRelation(Vobject* c, Vobject* p) : child(c), parent(p) {
00065             child->acquire(); // released by: ParentChildRelation() destructor
00066             parent->acquire(); // released by: ParentChildRelation() destructor
00067         }
00068         ~ParentChildRelation() {
00069             if(parent && child) {
00070                 LOG("vobject", 4, "deleting edge between child " << child->getURL().getString()
00071                     << " and parent " << parent->getURL().getString());
00072             } else if(parent) {
00073                 LOG("vobject", 4, "deleting dangling edge from parent " << parent->getURL().getString());
00074             } else if(child) {
00075                 LOG("vobject", 4, "deleting dangling edge to child " << child->getURL().getString());
00076             }
00077 
00078             if(child) child->release(); // acquired by: ParentChildRelation() constructor
00079             if(parent) parent->release(); // acquired by: ParentChildRelation() constructor
00080         }
00081         int position; /**< the position of the child in the parent's child list */
00082         string contextual_name; /**< the contextual name of the child in the parent's child list */
00083         Vobject* child; /**< the child object in question */
00084         Vobject* parent; /**< the parent object in question */
00085         /** This class is used internally to compare two ParentChildRelation structures
00086             to see if they represent the same relationship.
00087         */
00088         class Cmp {
00089         public:
00090             /** Compares two ParentChildRelation classes.
00091                 @param p left structure
00092                 @param q right
00093                 @return true if "p < q"; if the two are equal then ("p < q" || "q < p") is false.
00094             */
00095             inline bool operator()(const ParentChildRelation* p, const ParentChildRelation* q) const {
00096                 if(p->parent == q->parent) return (p->position < q->position);
00097                 else return (p->parent < q->parent);
00098             };
00099         };
00100     };
00101 
00102     typedef set<Vobject::ParentChildRelation*, Vobject::ParentChildRelation::Cmp> ParentSet;
00103     typedef deque<Vobject::ParentChildRelation*> ChildList;
00104     typedef set<string> TypeSet;
00105 
00106     /** An exception class thrown when the user attempts to read
00107         from the receiving queue and that queue is empty. */
00108     class MessageQueueEmptyError : public runtime_error {
00109     public:
00110         MessageQueueEmptyError(const string& s) : runtime_error(s) { };
00111     };
00112 
00113     /** An exception class thrown when a site lookup fails. */
00114     class NoSuchSiteError : public runtime_error {
00115     public:
00116         NoSuchSiteError(const string& s) : runtime_error(s) { };
00117     };
00118 
00119     /** An exception class thrown when an object lookup fails. */
00120     class NoSuchObjectError : public runtime_error {
00121     public:
00122         NoSuchObjectError(const string& s) : runtime_error(s) { };
00123     };
00124 
00125     class AccessControlError : public runtime_error {
00126     public:
00127         AccessControlError(const string& s) : runtime_error(s) { };
00128     };
00129 
00130     /** An exception class thrown when a remote action fails. */
00131     class RemoteError : public runtime_error {
00132     public:
00133         RemoteError(const string& s) : runtime_error(s) { };
00134     };
00135 
00136     /** An exception class thrown when an expected reply didn't arrive in the alloted time. */
00137     class TimeoutError : public RemoteError {
00138     public:
00139         TimeoutError(const string& s) : RemoteError(s) { };
00140     };
00141 
00142     /** Get the site name of this object.
00143         @return the name string
00144     */
00145     virtual const string& getName() = 0;
00146 
00147     /** Get the site this object resides on.
00148         @return the site object.   NOTE YOU MUST CALL release() WHEN DONE OR USE A rREF() BLOCK
00149     */
00150     virtual Site& getSite() = 0;
00151 
00152     /** Get the URL path (in the form "vop://site/name")
00153         @return the URL
00154     */
00155     virtual const URL& getURL() = 0;
00156 
00157     /** Return true if this object is local, false if not
00158         @return whether it is local
00159     */
00160     virtual bool isLocal() = 0;
00161 
00162     /** Return true if this object is remote, false if not
00163         @return whether it is remote
00164     */
00165     virtual bool isRemote() = 0;
00166 
00167     /** Return a set of type names for the types supported by this object.
00168         @return the set of type names
00169     */
00170     virtual const TypeSet& getTypes() throw (AccessControlError, RemoteError) = 0;
00171 
00172     /** Adds a new type to this object's type set.  This only changes
00173         the stored set of type name strings and does not necessarily
00174         affect the actual code behind the object.  See the Local Site
00175         class for information about extending the actual functionality
00176         of an existing meta objects.
00177         @param s the type string
00178     */
00179     virtual void addType(const string& s) = 0;
00180 
00181     /** Get the set of parent-child relationships in which this object is the child.
00182         @return a set of parent-child relations
00183     */
00184     virtual const ParentSet& getParents()
00185         throw (AccessControlError, RemoteError) = 0;
00186 
00187     /** Get the set of parent-child relationships in which this object is the parent.
00188         @return a set of parent-child relations
00189 
00190        @warning You should <em>always</em> assign the results of
00191        getChildren to a variable. Do NOT do this:
00192      @code
00193        for(Vobject::ChildList::const_iterator i = v->getChildren().begin();
00194             i != v->getChildren().end(); i++) {
00195             ...
00196        }
00197      @endcode
00198         Instead, you should do this:
00199      @code
00200        const ChildList& cl = v->getChildren();
00201        for(Vobject::ChildList::const_iterator i = cl.begin(); i != cl.end(); i++) {
00202             ...
00203        }
00204      @endcode
00205         The reason for this is that if vobj is remote, each call to
00206         getChildren() may trigger a remote call.  In addition to being
00207         inefficient, this will wipe and replace the child list you are
00208         in the midst of using, which will probably invalidate the
00209         iterator and cause your program to crash.
00210 
00211     */
00212     virtual const ChildList& getChildren() throw (AccessControlError, RemoteError) = 0;
00213 
00214     /** Sends a message to the object.  This may trigger immediate
00215         processing of the message if the object is local.
00216         @param m A pointer to the message which is being sent.  Its reference count will be increased as necssary.
00217     */
00218     virtual void sendMessage(Message* m) = 0;
00219 
00220     /** Sends a block of messages to the object.  This may trigger immediate
00221         processing of the message if the object is local.
00222         @param m A pointer to the message which is being sent.  Its reference count will be increased as necssary.
00223     */
00224     virtual void sendMessage(MessageBlock* m) = 0;
00225 
00226     /** Gets the next message the object has received.
00227         @throws MessageQueueEmptyError If the message queue is empty.
00228         This may be the case if there are no messages available or if
00229         the user has set DoNotQueueMsgs to true in
00230         VobjectImplementation.
00231         @return the message.    NOTE YOU MUST CALL release() WHEN DONE OR USE vRef!
00232     */
00233     virtual Message* receiveMessage() throw (MessageQueueEmptyError) = 0;
00234 
00235     /** Returns if the object has a message available to be dequeued by receiveMessage().
00236         @return True if receiveMessage will succeed, false if receiveMessage will throw an exception.
00237     */
00238     virtual bool hasMessageAvailable() = 0;
00239 
00240     /** Gets the next message the update object has received.  Update
00241         messages are special in that they consist of messages sent
00242         from remote sites to update changes to our local cache.
00243         @param m A pointer to the message which is being sent.  Its reference count will be increased as necssary.
00244     */
00245     virtual void sendUpdateMessage(Message* m) = 0;
00246 
00247     /** Gets the next update message the object has received.
00248         @throws MessageQueueEmptyError If the message queue is empty.
00249         This may be the case if there are no messages available or if
00250         the user has set DoNotQueueUpdateMsgs to true in
00251         VobjectImplementation.
00252         @return the message.    NOTE YOU MUST CALL release() WHEN DONE OR USE vRef!
00253     */
00254     virtual Message* receiveUpdateMessage() throw (MessageQueueEmptyError) = 0;
00255 
00256     /** Returns if the object has a message available to be dequeued
00257         by receiveUpdateMessage().
00258         @return True if receiveMessage() will succeed, false if
00259         receiveMessage will throw an exception.
00260     */
00261     virtual bool hasUpdateMessageAvailable() = 0;
00262 
00263     /** Searchs and returns some object, given a rooted path (that is,
00264         in the form "vop://site:port/child1/child2/etc").  See
00265         findObject() for more information about paths.
00266         @param path the path to the object we want to find
00267         @return the object, if found.  NOTE YOU MUST CALL release() WHEN DONE OR USE A rREF() BLOCK
00268         @throws NoSuchSiteError The DNS lookup for the site failed,
00269         the site is listening on the expected port, or the site
00270         otherwise could not be connected to
00271         @throws NoSuchObjectError if that object path does not exist on the site
00272         @throws URL::BadURLError if there is a syntax error in the supplied URL
00273         @throws AccessControlError if the site reported that the user is not allowed that information
00274     */
00275     static Vobject& findObjectFromRoot(const string& path)
00276         throw (NoSuchSiteError, NoSuchObjectError, URL::BadURLError, AccessControlError, RemoteError);
00277 
00278     /** Searchs and returns some object similarly to
00279         findObjectFromRoot().  However, if the path does not start
00280         with the string "vop://" the path will be intepreted as
00281         relative to this object.  For example, "foo/bar" will find the
00282         first child object named "foo" of this object, then the first
00283         child named "bar" of the "foo" object and return it.  If there
00284         is a leading slash, the path is relative to the object's site,
00285         so "/foo/bar" does @em not necessarily mean the same thing.
00286         Note that there should never be a slash at the end, so "foo/"
00287         is NOT a legal path.  Finally, instead of using child names,
00288         one may use "\#position", starting from zero.  So "\#0" refers
00289         to the first child of this object, "\#1" to the second etc.
00290         Obviously if the number in \#position is larger than the
00291         number of children, an exception will be raised.  See
00292         setChild() for more information about the possible numerical
00293         values of positions.
00294         @param path the path to the object we want to find
00295         @return the object, if found.  NOTE YOU MUST CALL release() WHEN DONE OR USE A rREF() BLOCK
00296         @throws NoSuchSiteError The DNS lookup for the site failed,
00297         the site is not listening on the expected port, or the site
00298         otherwise could not be connected to (only thrown if there is a
00299         site specified in the path.)
00300         @throws NoSuchObjectError if that object path does not exist on the site
00301         @throws URL::BadURLError if there is a syntax error in the supplied URL
00302         @throws AccessControlError if the site reported that the user is not allowed that information
00303     */
00304     virtual Vobject& findObject(const string& path)
00305         throw (NoSuchSiteError, NoSuchObjectError, URL::BadURLError, AccessControlError, RemoteError) = 0;
00306 
00307     /** Find a child.  This searchs for a single parent-child relation
00308         in the immediate child list of this object.  It is
00309         distinguished from findObject in that it returns the full
00310         parent-child relation structure, and that it only accepts two
00311         forms of input: the child name, or the \#position.  See
00312         setChild() for more information about the possible
00313         numerical values of positions.
00314         @param path either the child name or \#position
00315         @return the ParentChildRelation structure representing the
00316         relation of this parent and the requested child.   NOTE YOU MUST CALL release() WHEN DONE OR USE A rREF() BLOCK
00317         @throws NoSuchObjectError if the path is illegal
00318         @throws AccessControlError if the site reported the user is not allowed that information
00319     */
00320     virtual Vobject::ParentChildRelation& findChild(const string& path)
00321         throw (NoSuchObjectError, AccessControlError, RemoteError) = 0;
00322 
00323     /** Find a parent.  This tests to see if the supplied Vobject is
00324         marked as a parent of this Vobject.
00325         @param parent the parent object
00326         @returns the parent-child relation.   NOTE YOU MUST CALL release() WHEN DONE OR USE A rREF() BLOCK
00327         @throws NoSuchObjectError if the object is NOT a parent
00328         @throws AccessControlError if the site reported the user is not allowed that information
00329     */
00330     virtual Vobject::ParentChildRelation& findParent(Vobject& parent)
00331         throw (NoSuchObjectError, AccessControlError, RemoteError) = 0;
00332 
00333     /** Replace a child at some position with a new object.  @note On
00334         positions: if a position is zero or positive, its meaning is
00335         as you would expect, expressing the offset into an array of
00336         children.  However, if the position is negative, it expresses
00337         the offset from the end of the list.  This means for a list of
00338         length n, -1 is the last item in the list (equal to position
00339         position n - 1) and -n is the first item (equal to positive
00340         position 0).  This position notation is used in setChild()
00341         findObject(), findObjectFromRoot(), insertChild(), and
00342         removeChild(); it should also be available with any methods
00343         who make use of the previously-mentioned methods.
00344         @param position the position
00345         @param contextual_name This is the name, specific to this
00346         parent-child relation, used for refering to this object by
00347         path.
00348         @param child the child object, in question
00349         @throws AccessControl if this object (when it is remote)
00350         doesn't approve of this action.  */
00351     virtual void setChild(int position, const string& contextual_name, Vobject* child)
00352         throw (AccessControlError, RemoteError) = 0;
00353 
00354     /** Insert a child at some position with a new object.  If the
00355         position is positive, the object is inserted such that it now
00356         occupies that position, and all objects starting from the
00357         previous occupant of that position onward are moved up one.
00358         If the position in negative, the object is similarly inserted
00359         so that it now occupies that position.  For example, position
00360         -1 will append the object to the end of the list, position -2
00361         will insert the object in the second-to-last position, etc.  See
00362         setChild() for more information on positions.
00363         @param position the position
00364         @param contextual_name This is the name, specific to this
00365         parent-child relation, used for refering to this object by
00366         path.
00367         @param child the child object, in question
00368         @throws AccessControl if this object (when it is remote)
00369         doesn't approve of this action.
00370     */
00371     virtual void insertChild(int position,
00372                              const string& contextual_name,
00373                              Vobject* child)
00374         throw (AccessControlError, RemoteError) = 0;
00375 
00376     /** Remove the child at some position.  See setChild() for more
00377         information on positions.
00378         @param position the position
00379         @throws AccessControl if this object (when it is remote)
00380         doesn't approve of this action.  */
00381     virtual void removeChild(int position)
00382         throw (AccessControlError, RemoteError) = 0;
00383 
00384     /** Adds some object callback to be notified when the type set changes.
00385         @param tl the listener object.
00386         @param notifyImmediately  if true, notify listener immediately (before returning). otherwise defer until a future update
00387         If this object is also a RefCounted object, reference counting will be done correctly.
00388     */
00389     virtual void addTypeListener(TypeChangeListener* tl, bool notifyImmediately = true) = 0;
00390 
00391     /** Adds some object callback to be notified when the parent set changes.
00392         @param pl the listener object
00393         @poram notifyImmediately  if true, notify listener immediately (before returning). otherwise defer until a future update
00394         If this object is also a RefCounted object, reference counting will be done correctly.
00395     */
00396     virtual void addParentListener(ParentChangeListener* pl, bool notifyImmediately = true) = 0;
00397 
00398     /** Adds some object callback to be notified when the child list changes.
00399         The child listener will immediately be issued a notifyChildInserted() for
00400         each child.
00401         @param cl The listener object. If this object is also a RefCounted object, reference counting will be done correctly.
00402         @param notifyImmediately  if true, notify listener immediately (before returning). otherwise defer until a future update
00403     */
00404     virtual void addChildListener(ChildChangeListener* cl, bool notifyImmediately = true) = 0;
00405 
00406     /** Removes an existing object callback, previously added with addTypeListener().
00407         @param tl the listener object
00408         If this object is also a RefCounted object, reference counting will be done correctly.
00409     */
00410     virtual void removeTypeListener(TypeChangeListener* tl) = 0;
00411 
00412     /** Removes an existing object callback, previously added with addParentListener().
00413         @param pl the listener object
00414         If this object is also a RefCounted object, reference counting will be done correctly.
00415     */
00416     virtual void removeParentListener(ParentChangeListener* pl)= 0;
00417 
00418     /** Removes an existing object callback, previously added with addChildListener().
00419         @param cl the listener object
00420         If this object is also a RefCounted object, reference counting will be done correctly.
00421     */
00422     virtual void removeChildListener(ChildChangeListener* cl) = 0;
00423 
00424     /** Provide our own comparison function for objects which are logically
00425         equivilent in terms of the Vobject system.
00426         @param the object to compare this to
00427         @return v if these objects are equivalent
00428     */
00429     bool operator==(Vobject& v);
00430 
00431     /** Provide our own comparison function for objects which are logically
00432         equivilent in terms of the Vobject system.
00433         @param s the object to compare this to
00434         @return if these objects are equivalent
00435     */
00436     bool operator==(Vobject* v);
00437 
00438     /** Create a message block which, when run, will recreate any
00439         non-VOS state related to this vobject (such as property
00440         values).  In other words, it should not emit anything related
00441         to parent-child relationships, but is rather is a hook for
00442         other arbitrary state information, encoded as messages.
00443         @note Save-state routines ought to work for saving remote
00444         objects as well, based on available state.  Also, only the
00445         method and the message fields themselves should be used.  "To",
00446         "from", "nonce" and others will be ignored.
00447         @param output messages should be appended to this message block
00448         @param types the type set that should be output for this vobject
00449         @param portable If true, generate a "portable" state.  This
00450         means that all the data required to restore state should be
00451         embedded in the message.  If false, fully recreating the state
00452         may rely on external resources such as files or databases.
00453      */
00454     virtual void saveState(MessageBlock& output, set<string>& types, bool portable) = 0;
00455 
00456     /** Add a flag string.  Mainly useful for doing tree walks, when
00457         you want to mark an object as already having been touched.
00458         @param flag the flag string
00459      */
00460     virtual void addFlag(const string& flag) = 0;
00461 
00462     /** Remove a flag string.
00463         @param flag the flag string
00464      */
00465     virtual void removeFlag(const string& flag) = 0;
00466 
00467     /** Check the flag string.
00468         @param flag the flag string
00469         @return whether the flag string is set
00470      */
00471     virtual bool checkFlag(const string& flag) = 0;
00472 };
00473 
00474 
00475 /** A base implementation class for virtual objects.  Except for a few
00476     implementation-specific added methods, the API is the same as
00477     Vobject.
00478 
00479     @internal
00480 */
00481 class VOS_API VobjectImplementation : public virtual Vobject, public virtual ObjectExciseListener
00482 {
00483 private:
00484     bool islocal;
00485     bool exciseCalled;
00486     Site* site;
00487 protected:
00488     string name;
00489     URL url;
00490     deque<Message*> incomingMessageQueue;
00491     deque<Message*> incomingUpdateMessageQueue;
00492     set<ParentChildRelation*, Vobject::ParentChildRelation::Cmp> parents;
00493     deque<ParentChildRelation*> children;
00494     map<string, ParentChildRelation*> children_map;
00495     set<string> types;
00496     VobjectImplementation(const string& name, Site* remotesite, bool islocalobj);
00497     bool queueMsgs;
00498     bool queueUpdateMsgs;
00499     static bool queueMsgs_def;
00500     static bool queueUpdateMsgs_def;
00501     set<TypeChangeListener*> typeListeners;
00502     set<ParentChangeListener*> parentListeners;
00503     set<ChildChangeListener*> childListeners;
00504 
00505     set<string> flagstrings;
00506 
00507     class Dispatch
00508     {
00509     public:
00510         virtual ~Dispatch() {};
00511         virtual void sendMessage(Message* m) = 0;
00512         virtual bool equivalent(void*, void*) = 0;
00513         virtual bool holds(RefCounted* otherobj) = 0;
00514     };
00515 
00516     template<class T> class DispatchTemplate : public virtual Dispatch
00517     {
00518     private:
00519         T* thisobj;
00520         typedef void (T::* MessageHandler)(Message*);
00521         MessageHandler thismethod;
00522         bool needRelease;
00523     public:
00524         DispatchTemplate(T* theobj, MessageHandler themethod, bool doRefcount)
00525             : thisobj(theobj), thismethod(themethod), needRelease(doRefcount)
00526             {
00527                 if(doRefcount) {
00528                     if(RefCounted* rc = dynamic_cast<RefCounted*>(theobj)) {
00529                         rc->acquire(); // released by: destructor
00530                     }
00531                 }
00532             }
00533         virtual ~DispatchTemplate()
00534             {
00535                 if(needRelease) {
00536                 if(RefCounted* rc = dynamic_cast<RefCounted*>(thisobj)) {
00537                     rc->release(); // acquired by: constructor
00538                 }
00539                 }
00540         }
00541 
00542         virtual void sendMessage(Message* m) {
00543             (thisobj->*thismethod)(m);
00544         }
00545 
00546         virtual bool equivalent(void* otherobj, void* othermethod) {
00547             //return (otherobj == (void*)thisobj && othermethod == makevoid(thismethod));
00548             return (otherobj == (void*)thisobj);
00549         }
00550 
00551         virtual bool holds(RefCounted* otherobj) {
00552             return (dynamic_cast<RefCounted*>(thisobj) == otherobj);
00553         }
00554     };
00555 
00556     typedef multimap<string, Dispatch*> HandlerMap;
00557     HandlerMap msghandlers;
00558     HandlerMap updatehandlers;
00559 public:
00560     virtual ~VobjectImplementation();
00561 
00562     virtual const string& getName() { return name; };
00563     virtual Site& getSite();
00564     virtual const URL& getURL() { return url; }
00565     virtual bool isLocal() { return islocal; };
00566     virtual bool isRemote() { return (!islocal); };
00567 
00568     template<class T> void addMessageHandler(const string& method, T* theobj,
00569                                              void (T::* MessageHandler)(Message*),
00570                                              bool addExListener = false)
00571         {
00572             Dispatch* dt = new DispatchTemplate<T>(theobj, MessageHandler, addExListener);
00573             msghandlers.insert(HandlerMap::value_type(method, dt));
00574             if(addExListener) {
00575                 if(RefCounted* rc = dynamic_cast<RefCounted*>(theobj)) {
00576                     rc->addExciseListener(this);
00577                 }
00578             }
00579         };
00580 
00581     template<class T> void addUpdateHandler(const string& method, T* theobj,
00582                                             void (T::* MessageHandler)(Message*),
00583                                             bool addExListener = false)
00584         {
00585             Dispatch* dt = new DispatchTemplate<T>(theobj, MessageHandler, addExListener);
00586             updatehandlers.insert(HandlerMap::value_type(method, dt));
00587             if(addExListener) {
00588                 if(RefCounted* rc = dynamic_cast<RefCounted*>(theobj)) {
00589                     rc->addExciseListener(this);
00590                 }
00591             }
00592         };
00593 
00594     template<class T> void removeMessageHandler(const string& method, T* theobj,
00595                                                 void (T::* MessageHandler)(Message*))
00596         {
00597             pair<HandlerMap::iterator, HandlerMap::iterator> g = msghandlers.equal_range(method);
00598             for(HandlerMap::iterator it = g.first; it != g.second; it++) {
00599                 if((*it).second->equivalent(theobj, thehandler)) {
00600                     if(RefCounted* rc = dynamic_cast<RefCounted*>(theobj)) {
00601                         rc->removeExciseListener(this);
00602                     }
00603                     delete (*i).second;
00604                     msghandlers.erase(it);
00605                     break;
00606                 }
00607             }
00608         };
00609 
00610     template<class T> void removeUpdateHandler(const string& method, T* theobj,
00611                                                void (T::* MessageHandler)(Message*))
00612         {
00613             pair<HandlerMap::iterator, HandlerMap::iterator> g = updatehandlers.equal_range(method);
00614             for(HandlerMap::iterator it = g.first; it != g.second; it++) {
00615                 if((*it).second->equivalent(theobj, thehandler)) {
00616                     if(RefCounted* rc = dynamic_cast<RefCounted*>(theobj)) {
00617                         rc->removeExciseListener(this);
00618                     }
00619                     delete (*i).second;
00620                     updatehandlers.erase(it);
00621                     break;
00622                 }
00623             }
00624         };
00625 
00626     /** Get the default message discard policy for new objects.
00627         @return true if messages, after being passed through
00628         sendMessage(), are queued so they may be retrieved with
00629         receiveMessage(); false if the messages are instead discarded.
00630     */
00631     static bool getQueueMsgsDefault() { return queueMsgs_def; }
00632 
00633     /** Set the default message discard policy for new objects.
00634         @param t If false an incoming message, after being passed
00635         through sendMessage(), will be discarded.  If
00636         true that message will be queued and may be retrived by the
00637         user with receiveMessage().
00638     */
00639     static void setQueueMsgsDefault(bool t) { queueMsgs_def=t; }
00640 
00641     /** Get the default update message discard policy for new objects.
00642         @return true if update messages, after being passed through
00643         sendUpdateMessage(), are queued so they may be retrieved with
00644         receiveUpdateMessage(); false if the update messages are discarded.
00645     */
00646     static bool getQueueUpdateMsgsDefault() { return queueUpdateMsgs_def; }
00647 
00648     /** Set the default update message discard policy for new objects.
00649         @param t If false an incoming update message, after being passed
00650         through sendUpdateMessage(), will be discarded.  If
00651         true that update message will be queued and may be retrived by the
00652         user with receiveUpdateMessage().
00653     */
00654     static void setQueueUpdateMsgsDefault(bool t) { queueUpdateMsgs_def=t; }
00655 
00656     /** Get the message discard policy for this object.
00657         @return true if messages, after being passed through
00658         sendMessage(), are queued so they may be retrieved with
00659         receiveMessage(); false if the messages are instead discarded.
00660     */
00661     virtual bool getQueueMsgs() { return queueMsgs; }
00662 
00663     /** Set the message discard policy for this object.
00664         @param t If false an incoming message, after being passed
00665         through sendMessage(), will be discarded.  If
00666         true that message will be queued and may be retrived by the
00667         user with receiveMessage().
00668     */
00669     virtual void setQueueMsgs(bool t) { queueMsgs=t; }
00670 
00671     /** Get the update message discard policy for this object.
00672         @return true if update messages, after being passed through
00673         sendUpdateMessage(), are queued so they may be retrieved with
00674         receiveUpdateMessage(); false if the update messages are discarded.
00675     */
00676     virtual bool getQueueUpdateMsgs() { return queueUpdateMsgs; }
00677 
00678     /** Set the update message discard policy for this object.
00679         @param t If false an incoming update message, after being passed
00680         through sendUpdateMessage(), will be discarded.  If
00681         true that update message will be queued and may be retrived by the
00682         user with receiveUpdateMessage().
00683     */
00684     virtual void setQueueUpdateMsgs(bool t) { queueUpdateMsgs=t; }
00685 
00686     virtual const TypeSet& getTypes()
00687         throw (AccessControlError, RemoteError);
00688 
00689     virtual void addType(Vobject* requester, const string& s);
00690 
00691     virtual const ParentSet& getParents()
00692         throw (AccessControlError, RemoteError);
00693     virtual const ChildList& getChildren()
00694         throw (AccessControlError, RemoteError);
00695 
00696     virtual Message* receiveMessage() throw (MessageQueueEmptyError);
00697     virtual bool hasMessageAvailable();
00698 
00699     void sendUpdateMessage(Message* m);
00700     virtual Message* receiveUpdateMessage() throw (MessageQueueEmptyError);
00701     virtual bool hasUpdateMessageAvailable();
00702 
00703     virtual Vobject& findObject(const string& path)
00704         throw (NoSuchSiteError, NoSuchObjectError, URL::BadURLError, AccessControlError, RemoteError);
00705     virtual Vobject::ParentChildRelation& findChild(const string& path)
00706         throw (NoSuchObjectError, AccessControlError, RemoteError);
00707     virtual Vobject::ParentChildRelation& findParent(Vobject& parent)
00708         throw (NoSuchObjectError, AccessControlError, RemoteError);
00709 
00710     virtual void setChild(Vobject* requester, int position, const string& contextual_name, Vobject* child)
00711         throw (AccessControlError, RemoteError);
00712     virtual void insertChild(Vobject* requester, int position, const string& contextual_name, Vobject* child)
00713         throw (AccessControlError, RemoteError);
00714     virtual void removeChild(Vobject* requester, int position)
00715         throw (AccessControlError, RemoteError);
00716 
00717     virtual void addTypeListener(TypeChangeListener* tl, bool refresh = true);
00718     virtual void addParentListener(ParentChangeListener* pl, bool refresh = true);
00719     virtual void addChildListener(ChildChangeListener* cl, bool refresh = true);
00720     virtual void removeTypeListener(TypeChangeListener* tl);
00721     virtual void removeParentListener(ParentChangeListener* pl);
00722     virtual void removeChildListener(ChildChangeListener* cl);
00723 
00724     virtual void notifyObjectExcise(RefCounted* rc);
00725 
00726     virtual void excise();
00727 
00728     virtual void saveState(MessageBlock& output, set<string>& types, bool portable);
00729 
00730     virtual void addFlag(const string& flag);
00731     virtual void removeFlag(const string& flag);
00732     virtual bool checkFlag(const string& flag);
00733 
00734     friend class RemoteVobject;
00735 };
00736 }
00737 
00738 #endif

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