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/remotevobject.cc

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 */
00023 
00024 #include "remotesite.hh"
00025 #include "message.hh"
00026 
00027 using namespace VOS;
00028 
00029 #include <stdio.h>
00030 #include <signal.h> // this is temporary and not very portable
00031 
00032 #include <string>
00033 #include <algorithm>
00034 
00035 /** @file
00036     Implements RemoteVobject.
00037 */
00038 
00039 RemoteVobject::RemoteVobject(const string& name, RemoteSite* s)
00040     : VobjectImplementation(name, s, false), resetChildren(false)
00041 {
00042     addUpdateHandler<RemoteVobject>("core:set-child-update", this, &RemoteVobject::addChildUpdateHandler);
00043     addUpdateHandler<RemoteVobject>("core:insert-child-update", this, &RemoteVobject::addChildUpdateHandler);
00044     addUpdateHandler<RemoteVobject>("core:insert-parent-update", this, &RemoteVobject::addParentUpdateHandler);
00045     addUpdateHandler<RemoteVobject>("core:remove-child-update", this, &RemoteVobject::removeChildUpdateHandler);
00046     addUpdateHandler<RemoteVobject>("core:remove-parent-update", this, &RemoteVobject::removeParentUpdateHandler);
00047     addUpdateHandler<RemoteVobject>("core:type-add-update", this, &RemoteVobject::typeUpdateHandler);
00048     addUpdateHandler<RemoteVobject>("core:start-listening-reply", this, &RemoteVobject::addListenerReplyHandler);
00049 }
00050 
00051 void RemoteVobject::sendMessage(Message* m)
00052 {
00053     rREF(Site&, site, getSite(), site.sendMessage(m));
00054 }
00055 
00056 void RemoteVobject::sendMessage(MessageBlock* mb)
00057 {
00058     rREF(Site&, site, getSite(), site.sendMessage(mb));
00059 }
00060 
00061 RemoteVobject::~RemoteVobject()
00062 {
00063 }
00064 
00065 LocalSite& RemoteVobject::initFields(Vobject* v, Message* m, const string& method, bool withnonce)
00066 {
00067     m->setType("message");
00068     LocalSite* ls;
00069     vRef<Site> s = v->getSite();
00070     ls = &(dynamic_cast<RemoteSite*>(&s)->getLocalPeer()); // released by: the caller of this method
00071 
00072     m->setFrom(ls->getURL().getString());
00073     m->setTo(v->getURL().getString());
00074     m->setMethod(method);
00075     if(withnonce) m->generateNonce();
00076 
00077     // pass reference to ls through
00078     return *ls;
00079 }
00080 
00081 Vobject& RemoteVobject::findObject(const string& path)
00082     throw (NoSuchSiteError, NoSuchObjectError, URL::BadURLError, AccessControlError, RemoteError)
00083 {
00084     try {
00085         // pass reference through
00086         return VobjectImplementation::findObject(path);
00087     } catch(NoSuchObjectError) { }
00088 
00089     unsigned int nextpart;
00090     string nextchild;
00091     if(path[0] == '/') {
00092         rREF(Site&, site, getSite(),
00093              Vobject& v = site.findObject(path.substr(1));
00094              site.release();   // acquired by: getSite() above
00095              return v;         // pass reference through
00096             ); // will catch any exceptions, release the site, and re-throw the exception
00097     } else {
00098         nextpart = (unsigned int)path.find("/");
00099         nextchild = path.substr(0, nextpart).c_str();
00100     }
00101 
00102     vRef<ParentChildRelation> f = findChild(nextchild);
00103     /*
00104     pREF(Message*, m, new Message(),
00105          rREF(LocalSite&, ls, initFields(this, m, "core:find-child", true),
00106               m->insertField(-1, "path", nextchild);
00107 
00108               sendMessage(m);
00109               rREF(Site&, site, getSite(),
00110                    pREF(Message*, r, ls.waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site)), ));
00111              );
00112         );
00113     */
00114     // pass reference through
00115     return VobjectImplementation::findObject(path);
00116 }
00117 
00118 const deque<Vobject::ParentChildRelation*>& RemoteVobject::getChildren() throw (AccessControlError, RemoteError)
00119 {
00120     if(childListeners.empty()) {
00121         vRef<Message> m = new Message();
00122         vRef<LocalSite> ls = initFields(this, &m, "core:find-child", true);
00123         m->insertField(-1, "path", "#0");
00124         m->insertField(-1, "to", "");
00125         m->insertField(-1, "path", "#-1");
00126 
00127         sendMessage(&m);
00128 
00129         resetChildren = true;
00130 
00131         vRef<Site> site = getSite();
00132         vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00133     }
00134 
00135     return children;
00136 }
00137 
00138 const set<Vobject::ParentChildRelation*, Vobject::ParentChildRelation::Cmp>& RemoteVobject::getParents()
00139     throw (AccessControlError, RemoteError)
00140 {
00141     if(parentListeners.empty()) {
00142         pREF(Message*, m, new Message(),
00143              rREF(Site&, site, getSite(),
00144                   rREF(LocalSite&, ls, initFields(this, m, "core:get-parents", true),
00145                        sendMessage(m);
00146                        pREF(Message*, r, ls.waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site)), );
00147                       );
00148                  );
00149             );
00150     }
00151 
00152     return parents;
00153 }
00154 
00155 void RemoteVobject::addChildUpdateHandler(Message* m)
00156 {
00157     vRef<Site> s = getSite();
00158     try {
00159         if(&s == dynamic_cast<Site*>(this)) {
00160             resetChildren=false;
00161         } else {
00162             if(resetChildren && m->getMethod() == "core:set-child-update") {
00163                 if(children.size() > 0) {
00164                     for(int i = (int)children.size() - 1; i >= 0; i--) {
00165                         VobjectImplementation::removeChild(this, i);
00166                     }
00167                 }
00168                 resetChildren=false;
00169             }
00170             s->lockNotificationFlush();
00171             for(int i=0; i < m->getNumFields(); ++i) {
00172                 const Message::Field& pos=m->getField(i);
00173                 if(pos.key != "pos") break;
00174                 const Message::Field& name=m->getField(++i);
00175                 if(name.key != "name") break;
00176                 const Message::Field& path=m->getField(++i);
00177                 if(path.key != "path") break;
00178                 try {
00179                     int position=abs(atoi(pos.value.c_str()));
00180                     LOG("sendUpdateMessage", 5, "adding child " + name.value
00181                         + " at position " + pos.value);
00182                     vRef<Vobject> child = Vobject::findObjectFromRoot(path.value);
00183                     /*if(! (position < children.size()
00184                       && children[position]
00185                       && children[position]->child == child
00186                       && children[position]->contextual_name == name.value)) {*/
00187                     bool clc=false;
00188                     //bool lc=false;
00189                     bool clp=false;
00190                     bool plp=false;
00191                     bool plc=false;
00192                     vRef<RemoteSite> cs = dynamic_cast<RemoteSite*>(&(child->getSite()));
00193                     if(childListeners.count(&cs)) {
00194                         clc=true;
00195                         childListeners.erase(&cs);
00196                     }
00197                     if(parentListeners.count(&cs)) {
00198                         plc=true;
00199                         parentListeners.erase(&cs);
00200 
00201                     }
00202                     vRef<RemoteSite> ps = dynamic_cast<RemoteSite*>(&(getSite()));
00203                     if(childListeners.count(&*(ps))) {
00204                         clp=true;
00205                         childListeners.erase(&ps);
00206                     }
00207                     if(parentListeners.count(&ps)) {
00208                         plp=true;
00209                         parentListeners.erase(&ps);
00210                     }
00211 
00212                     if(m->getMethod() == "core:set-child-update")
00213                         VobjectImplementation::setChild(this, position, name.value, &child);
00214                     else
00215                         VobjectImplementation::insertChild(this, position, name.value, &child);
00216 
00217                     if(clc) childListeners.insert(&cs);
00218                     if(plc) parentListeners.insert(&cs);
00219                     if(clp) childListeners.insert(&ps);
00220                     if(plp) parentListeners.insert(&ps);
00221                 } catch(NoSuchSiteError) {
00222                 } catch(NoSuchObjectError) {
00223                 } catch(URL::BadURLError) {
00224                 } catch(AccessControlError) {
00225                 } catch(RemoteError) {
00226                 }
00227             }
00228         }
00229         s->unlockNotificationFlush();
00230     } catch(Message::NoSuchFieldError) {
00231         s->unlockNotificationFlush();
00232         LOG("remotevobject", 2, "Message missing a field on insert/set child?");
00233     } catch(runtime_error e) {
00234         s->unlockNotificationFlush();
00235         LOG("remotevobject", 2, "Caught exception processing insert/set child: " << e.what());
00236     } catch(...) {
00237         LOG("remotevobject", 2, "Something very bad just happened in insert/set child!");
00238         s->unlockNotificationFlush();
00239     }
00240 }
00241 
00242 void RemoteVobject::addParentUpdateHandler(Message* m)
00243 {
00244     try {
00245         for(int i=0; i < m->getNumFields(); ++i) {
00246             const Message::Field& pos=m->getField(i);
00247             if(pos.key != "pos") break;
00248             const Message::Field& name=m->getField(++i);
00249             if(name.key != "name") break;
00250             const Message::Field& path=m->getField(++i);
00251             if(path.key != "path") break;
00252             try {
00253                 int position=atoi(pos.value.c_str());
00254                 LOG("sendUpdateMessage", 5, "adding parent " + name.value
00255                     + " at position " + pos.value);
00256                 pREF(Vobject*, parent, &(Vobject::findObjectFromRoot(path.value)),
00257                      if(MetaObject *m=dynamic_cast<MetaObject*>(parent)) parent=m->getTopObject();
00258                      RemoteVobject* rvo = dynamic_cast<RemoteVobject*>(parent);
00259                      if(rvo && rvo->childListeners.empty()) {
00260                          rvo->VobjectImplementation::setChild(this, position, name.value, this);
00261                      }
00262                     );
00263             } catch(NoSuchObjectError) { }
00264         }
00265     } catch(Message::NoSuchFieldError) { }
00266 }
00267 
00268 void RemoteVobject::removeChildUpdateHandler(Message* m)
00269 {
00270     try {
00271         for(int i=0; i < m->getNumFields(); ++i) {
00272             const Message::Field& pos=m->getField(i);
00273             if(pos.key != "pos") break;
00274             const Message::Field& name=m->getField(++i);
00275             if(name.key != "name") break;
00276             const Message::Field& path=m->getField(++i);
00277             if(path.key != "path") break;
00278 
00279             try {
00280                 //rREF(Vobject&, v, Vobject::findObjectFromRoot(path.value),
00281                 unsigned int posi=abs(atoi(pos.value.c_str()));
00282                 if(posi < children.size() && children[posi] && children[posi]->contextual_name == name.value
00283                    /*&& *children[posi]->child == v*/) {
00284                     VobjectImplementation::removeChild(this, posi);
00285                 }
00286                 //);
00287             } catch(NoSuchObjectError) {
00288             }
00289         }
00290     } catch(Message::NoSuchFieldError) {
00291     }
00292 }
00293 
00294 void RemoteVobject::removeParentUpdateHandler(Message* m)
00295 {
00296     try {
00297         for(int i=0; i < m->getNumFields(); ++i) {
00298             const Message::Field& pos=m->getField(i);
00299             if(pos.key != "pos") break;
00300             const Message::Field& name=m->getField(++i);
00301             if(name.key != "name") break;
00302             const Message::Field& path=m->getField(++i);
00303             if(path.key != "path") break;
00304             try {
00305                 int position=atoi(pos.value.c_str());
00306                 LOG("sendUpdateMessage", 5, "removing parent " + name.value
00307                     + " at position " + pos.value);
00308                 pREF(Vobject*, parent, &(Vobject::findObjectFromRoot(path.value)),
00309                      RemoteVobject* rvo = dynamic_cast<RemoteVobject*>(parent);
00310                      if(rvo && rvo->childListeners.empty()) {
00311                          parent->removeChild(position);
00312                      }
00313                     );
00314             } catch(NoSuchObjectError) { }
00315         }
00316     } catch(Message::NoSuchFieldError) { }
00317 }
00318 
00319 void RemoteVobject::typeUpdateHandler(Message* m)
00320 {
00321     for(int i=0; i < m->getNumFields(); ++i) {
00322         const Message::Field& t=m->getField(i);
00323         if(t.key == "type") types.insert(t.value);
00324     }
00325 }
00326 
00327 
00328 
00329 void RemoteVobject::sendUpdateMessage(Message* m)
00330 {
00331     //LOG("refcount", 5, "sendUpdateMessage: count on this rv's rs is " << site->getCount());
00332     LOG("refcount", 5, "before sending to VobjectImp::sendUpdateMessage count on message " << m->getCount());
00333     VobjectImplementation::sendUpdateMessage(m);
00334     LOG("refcount", 5, "after sending to VobjectImp::sendUpdateMessage count on message " << m->getCount());
00335 
00336 
00337     LOG("refcount", 5, "before doing stuff, count on message " << m->getCount() << " numchildren " << (unsigned int)children.size());
00338 
00339     pair<HandlerMap::iterator, HandlerMap::iterator> hndls = updatehandlers.equal_range(m->getMethod());
00340     for(HandlerMap::iterator i = hndls.first; i !=  hndls.second; i++) {
00341         try {
00342             (*i).second->sendMessage(m);
00343         } catch(NoSuchObjectError) {
00344         } catch(NoSuchSiteError) {
00345         } catch(URL::BadURLError) {
00346         } catch(AccessControlError) {
00347         }
00348     }
00349 
00350     LOG("refcount", 5, "after doing stuff, count on message " << m->getCount());
00351 
00352 
00353     //LOG("refcount", 5, "sendUpdateMessage: count on this rv's rs NOW is " << site->getCount());
00354 }
00355 
00356 void RemoteVobject::addListenerReplyHandler(Message* m)
00357 {
00358     try {
00359         const Message::Field& f = m->getField("listen");
00360         if(f.value == "types") {
00361             VobjectImplementation::addTypeListener(&DoNothingListener::static_);
00362         } else if(f.value == "parents") {
00363             VobjectImplementation::addParentListener(&DoNothingListener::static_);
00364         } else if(f.value == "children") {
00365             VobjectImplementation::addChildListener(&DoNothingListener::static_);
00366         }
00367     } catch(Message::NoSuchFieldError) { }
00368 }
00369 
00370 const set<string>& RemoteVobject::getTypes() throw (AccessControlError, RemoteError)
00371 {
00372     try {
00373         //LOG("refcount", 5, "getTypes: count on this rv's rs is " << site->getCount());
00374         if(types.size() == 0) {
00375             pREF(Message*, m, new Message(),
00376                 rREF(LocalSite&, ls, initFields(this, m, "core:get-types", true),
00377                     //LOG("refcount", 5, "getTypes: count on this rv's rs NOW is " << site->getCount());
00378                     sendMessage(m);
00379                     //LOG("refcount", 5, "getTypes: count on this rv's rs post-sendMsg is " << site->getCount());
00380                     rREF(Site&, site, getSite(),
00381                         pREF(Message*, r, ls.waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site)), ));
00382                     //LOG("refcount", 5, "getTypes: count on this rv's rs post-waitFor is " << site->getCount());
00383                     );
00384                 );
00385         }
00386         return VobjectImplementation::getTypes();
00387     } catch(AccessControlError) {
00388         throw;
00389     } catch(RemoteError) {
00390         throw;
00391     } catch(exception& e) {
00392         LOG("RemoteVobject", 0, "ERROR (unexpected exception): " << e.what());
00393         throw;
00394     }
00395 }
00396 
00397 Vobject::ParentChildRelation& RemoteVobject::findChild(const string& path)
00398     throw (NoSuchObjectError, AccessControlError, RemoteError)
00399 {
00400     try {
00401         // pass reference through
00402         return VobjectImplementation::findChild(path);
00403     } catch(NoSuchObjectError) {
00404         if(! childListeners.empty()) throw;
00405     }
00406 
00407     pREF(Message*, m, new Message(),
00408          rREF(LocalSite&, ls, initFields(this, m, "core:find-child", true),
00409               m->insertField(-1, "path", path);
00410 
00411               sendMessage(m);
00412               rREF(Site&, site, getSite(),
00413                    pREF(Message*, r, ls.waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site)), ));
00414              );
00415         );
00416 
00417     // pass reference through
00418     return VobjectImplementation::findChild(path);
00419 }
00420 
00421 /** @note supplying a NULL for child means release child object but do not delete parent-child relation... */
00422 void RemoteVobject::setChild(int position, const string& contextual_name, Vobject* child)
00423     throw (AccessControlError, RemoteError)
00424 {
00425     if(!child) {
00426         if(position < 0) position = (int)children.size() + position;
00427         if(position >= (int)children.size()) position = position % (int)children.size();
00428         ParentChildRelation* pcr = children[position];
00429         if(pcr->contextual_name != contextual_name) return;
00430 
00431         vRef<Site> thissite = getSite();
00432 
00433         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ChildRemove, *this, *this,
00434                                                     position, pcr->contextual_name, *(pcr->child));
00435 
00436         for(set<ChildChangeListener*>::iterator i = childListeners.begin();
00437             i != childListeners.end(); i++)
00438         {
00439             try {
00440                 (*i)->notifyChildRemoved(*event);
00441             } catch(runtime_error e) {
00442                 LOG("remotevobject", 2, "notifyChildRemoved emitted exception: " << e.what());
00443             } catch(...) {
00444                 LOG("remotevobject", 2, "notifyChildRemoved emitted unknown exception");
00445             }
00446         }
00447 
00448         if(VobjectImplementation* v = dynamic_cast<VobjectImplementation*>(pcr->child)) {
00449             v->parents.erase(pcr);
00450             pcr->release(); // acquired by: insertChild() or setChild()
00451         }
00452         pcr->child->release(); // acquired by: insertChild() or setChild()
00453         pcr->child = 0;
00454         return;
00455     }
00456 
00457     if((int)children.size() > position
00458        && children[position]
00459        && children[position]->child == child
00460        && children[position]->contextual_name == contextual_name) return;
00461 
00462     pREF(Message*, m, new Message(),
00463          rREF(LocalSite&, ls, initFields(this, m, "core:set-child", true),
00464               char pos[16];
00465               snprintf(pos, sizeof(pos), "%i", position);
00466               m->insertField(-1, "pos", string(pos));
00467               m->insertField(-1, "name", contextual_name);
00468               m->insertField(-1, "path", child->getURL().getString());
00469 
00470               sendMessage(m);
00471               rREF(Site&, site, getSite(),
00472                    pREF(Message*, r, ls.waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site)), ));
00473              );
00474         );
00475 }
00476 
00477 void RemoteVobject::insertChild(int position, const string& contextual_name, Vobject* child)
00478     throw (AccessControlError, RemoteError)
00479 {
00480     pREF(Message*, m, new Message(),
00481          rREF(LocalSite&, ls, initFields(this, m, "core:insert-child", true),
00482               char pos[16];
00483               snprintf(pos, sizeof(pos), "%i", position);
00484               m->insertField(-1, "pos", string(pos));
00485               m->insertField(-1, "name", contextual_name);
00486               m->insertField(-1, "path", child->getURL().getString());
00487 
00488               sendMessage(m);
00489               rREF(Site&, site, getSite(),
00490                    pREF(Message*, r, ls.waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site)), ));
00491              );
00492         );
00493 }
00494 
00495 void RemoteVobject::removeChild(int position)
00496     throw (AccessControlError, RemoteError)
00497 {
00498     vRef<Message> m = new Message();
00499     vRef<LocalSite> ls = initFields(this, &m, "core:remove-child", true);
00500     char pos[16];
00501     snprintf(pos, sizeof(pos), "%i", position);
00502     m->insertField(-1, "pos", pos);
00503     m->insertField(-1, "name", children[position]->contextual_name);
00504     m->insertField(-1, "path", children[position]->child->getURL().getString());
00505 
00506     sendMessage(&m);
00507 
00508     vRef<Site> site = getSite();
00509     try{
00510         vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00511     } catch(exception& e) {
00512         LOG("remotevobject", 2, "RemoteVobject::removeChild: caught exception from waitFor: " << e.what());
00513     }
00514 }
00515 
00516 void RemoteVobject::addTypeListener(TypeChangeListener* tl, bool refresh)
00517 {
00518     if(typeListeners.empty() && refresh) {
00519             types.clear();
00520 
00521             vRef<Message> m = new Message();
00522             vRef<LocalSite> ls = initFields(this, &m, "core:start-listening", true);
00523             m->insertField(-1, "listen", "types");
00524             sendMessage(&m);
00525             vRef<Site> site = getSite();
00526             vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00527     }
00528     VobjectImplementation::addTypeListener(tl, refresh);
00529 }
00530 
00531 void RemoteVobject::addParentListener(ParentChangeListener* pl, bool refresh)
00532 {
00533     if(parentListeners.empty() && refresh) {
00534             vRef<Message> m = new Message();
00535             vRef<LocalSite> ls = initFields(this, &m, "core:start-listening", true);
00536             m->insertField(-1, "listen", "parents");
00537 
00538             sendMessage(&m);
00539             vRef<Site> site = getSite();
00540             vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00541     }
00542     VobjectImplementation::addParentListener(pl, refresh);
00543 }
00544 
00545 void RemoteVobject::addChildListener(ChildChangeListener* cl, bool refresh)
00546 {
00547     if(childListeners.empty() && refresh) {
00548         vRef<Message> m = new Message();
00549         vRef<LocalSite> ls = initFields(this, &m, "core:start-listening", true);
00550         m->insertField(-1, "listen", "children");
00551 
00552         sendMessage(&m);
00553         vRef<Site> site = getSite();
00554         vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00555     }
00556     VobjectImplementation::addChildListener(cl, refresh);
00557 }
00558 
00559 void RemoteVobject::removeTypeListener(TypeChangeListener* tl)
00560 {
00561     VobjectImplementation::removeTypeListener(tl);
00562     if(typeListeners.size() == 1 && typeListeners.count(&DoNothingListener::static_) == 1)
00563         typeListeners.erase(&DoNothingListener::static_);
00564 
00565     if(typeListeners.empty()) {
00566         pREF(Message*, m, new Message(),
00567              rREF(LocalSite&, ls, initFields(this, m, "core:stop-listening", false), );
00568              m->insertField(-1, "listen", "types");
00569 
00570              sendMessage(m);
00571             );
00572     }
00573 }
00574 
00575 void RemoteVobject::removeParentListener(ParentChangeListener* pl)
00576 {
00577     VobjectImplementation::removeParentListener(pl);
00578     if(parentListeners.size() == 1 && parentListeners.count(&DoNothingListener::static_) == 1)
00579         parentListeners.erase(&DoNothingListener::static_);
00580 
00581     if(parentListeners.empty()) {
00582         pREF(Message*, m, new Message(),
00583              rREF(LocalSite&, ls, initFields(this, m, "core:stop-listening", false), );
00584              m->insertField(-1, "listen", "parents");
00585 
00586              sendMessage(m);
00587             );
00588     }
00589 }
00590 
00591 void RemoteVobject::removeChildListener(ChildChangeListener* cl)
00592 {
00593     VobjectImplementation::removeChildListener(cl);
00594     if(childListeners.size() == 1 && childListeners.count(&DoNothingListener::static_) == 1)
00595         childListeners.erase(&DoNothingListener::static_);
00596 
00597     if(childListeners.empty()) {
00598         pREF(Message*, m, new Message(),
00599              rREF(LocalSite&, ls, initFields(this, m, "core:stop-listening", false), );
00600              m->insertField(-1, "listen", "children");
00601 
00602              sendMessage(m);
00603             );
00604     }
00605 }
00606 
00607 void RemoteVobject::addType(const string& s)
00608 {
00609     vRef<Message> m = new Message();
00610     vRef<LocalSite> ls = initFields(this, &m, "core:type-add", true);
00611     m->insertField(-1, "type", s);
00612 
00613     sendMessage(&m);
00614 
00615     vRef<Site> site = getSite();
00616     try{
00617         vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00618     } catch(exception& e) {
00619         LOG("remotevobject", 2, "RemoteVobject::removeChild: caught exception from waitFor: " << e.what());
00620     }
00621 }
00622 
00623 
00624 void RemoteVobject::acquire()
00625 {
00626     RefCounted::acquire();
00627     LOG("refcount", 5, "acquire called on " << getURL().getString() << " count is now " << getCount());
00628 }
00629 
00630 void RemoteVobject::release()
00631 {
00632     LOG("refcount", 5, "release called on " << getURL().getString() << " count is now " << (getCount()-1));
00633     RefCounted::release();
00634 }

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