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

Go to the documentation of this file.
00001 /*
00002     This file is part of the Virtual Object System of
00003     the Interreality project.
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 
00025 #include "bufferedproperty.hh"
00026 
00027 set<BufferedLocalProperty*> BufferedLocalProperty::allblps;
00028 set<BufferedRemoteProperty*> BufferedRemoteProperty::allbrps;
00029 
00030 /* BufferedLocalProperty definition */
00031 
00032 BufferedLocalProperty::BufferedLocalProperty(MetaObject* superobject)
00033     : MetaObject(superobject), Property(superobject), LocalProperty(superobject), changed(false)
00034 {
00035     allblps.insert(this);
00036 }
00037 
00038 BufferedLocalProperty::BufferedLocalProperty(MetaObject* superobject, const string& d, const string& dt)
00039     : MetaObject(superobject), Property(superobject), LocalProperty(superobject, d, dt), changed(false)
00040 {
00041     allblps.insert(this);
00042 }
00043 
00044 BufferedLocalProperty::~BufferedLocalProperty()
00045 {
00046     allblps.erase(this);
00047 }
00048 
00049 MetaObject* BufferedLocalProperty::new_BufferedLocalProperty(MetaObject* superobject, const string& type)
00050 {
00051     return new BufferedLocalProperty(superobject);
00052 }
00053 
00054 void BufferedLocalProperty::write(int start, const string& newdata)
00055 {
00056     string oldvalue;
00057     read(oldvalue);
00058 
00059     Property::write(start, newdata);
00060 
00061     vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyWrite,
00062                                                   *this, *this,
00063                                                   start, newdata.size(),
00064                                                   read(), getDataType(),
00065                                                   oldvalue, getDataType(),
00066                                                   false);
00067 
00068     for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00069         if(! dynamic_cast<PropertyListenerSiteWrapper*>((*i).second))
00070             (*i).second->notifyPropertyChange(*event);
00071     }
00072     changed = true;
00073     changestart = start;
00074     changelen = newdata.length();
00075 }
00076 
00077 void BufferedLocalProperty::replace(const string& newdata, const string& newtype)
00078 {
00079     string oldvalue;
00080     read(oldvalue);
00081 
00082     Property::replace(newdata, newtype);
00083     string r;
00084     read(r);
00085 
00086     vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyReplace,
00087                                                   *this, *this,
00088                                                   read(), getDataType(),
00089                                                   oldvalue, getDataType(),
00090                                                   false);
00091 
00092 
00093     for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00094         if(! dynamic_cast<PropertyListenerSiteWrapper*>((*i).second))
00095             (*i).second->notifyPropertyChange(*event);
00096     }
00097     changed = true;
00098     changestart = 0;
00099     changelen = getLength();
00100 }
00101 
00102 void BufferedLocalProperty::flush()
00103 {
00104         if(changed) {
00105 
00106             vRef<PropertyEvent> event;
00107             if(changestart == 0 && changelen == getLength()) {
00108                 event = new PropertyEvent(PropertyEvent::PropertyReplace,
00109                                       *this, *this,
00110                                       read(), getDataType(),
00111                                       false);
00112             } else {
00113                 event = 
00114                     new PropertyEvent(PropertyEvent::PropertyWrite,
00115                                       *this, *this,
00116                                       changestart, changelen,
00117                                       read(), getDataType(),
00118                                       false);
00119 
00120             }
00121 
00122             for(PropertyListenerMap::iterator n = propertyListeners.begin();
00123                 n != propertyListeners.end(); n++) {
00124                 string s;
00125                 readRaw(s, changestart, changelen);
00126                 if(dynamic_cast<PropertyListenerSiteWrapper*>((*n).second)) {
00127                     (*n).second->notifyPropertyChange(*event);
00128                 }
00129             }
00130             changed = false;
00131         }
00132 }
00133 
00134 void BufferedLocalProperty::flushAll()
00135 {
00136     for(set<BufferedLocalProperty*>::iterator i = allblps.begin(); i != allblps.end(); i++) {
00137         try {
00138             (*i)->flush();
00139         } catch(runtime_error e) {
00140             LOG("bufferedproperty", 2, "flushAll caught exception: " << e.what());
00141         }
00142     }
00143 }
00144 
00145 void BufferedLocalProperty::registerExtenders()
00146 {
00147     static bool done = false;
00148     if(! done) {
00149     LocalSite::addLocalObjectExtension(typeid(BufferedLocalProperty).name(),
00150                                          &BufferedLocalProperty::new_BufferedLocalProperty);
00151     LocalSite::addLocalObjectExtension(typeid(LocalProperty).name(),
00152                                          &BufferedLocalProperty::new_BufferedLocalProperty);
00153     LocalSite::addLocalObjectExtension(typeid(Property).name(),
00154                                          &BufferedLocalProperty::new_BufferedLocalProperty);
00155     LocalSite::addLocalObjectExtension("property:property",
00156                                          &BufferedLocalProperty::new_BufferedLocalProperty);
00157     done = true;
00158     }
00159 }
00160 
00161 /* BufferedRemoteProperty definition */
00162 
00163 BufferedRemoteProperty::BufferedRemoteProperty(MetaObject* superobject)
00164     : MetaObject(superobject), Property(superobject), RemoteProperty(superobject), changed(false), lastmsgsuccess(false)
00165 {
00166     allbrps.insert(this);
00167 }
00168 
00169 MetaObject* BufferedRemoteProperty::new_BufferedRemoteProperty(MetaObject* superobject, const string& type)
00170 {
00171     return new BufferedRemoteProperty(superobject);
00172 }
00173 
00174 BufferedRemoteProperty::~BufferedRemoteProperty()
00175 {
00176     allbrps.erase(this);
00177 }
00178 
00179 void BufferedRemoteProperty::write(int start, const string& newdata)
00180 {
00181     string oldvalue;
00182     Property::read(oldvalue);
00183 
00184     Property::write(start, newdata);
00185     changed = true;
00186     changestart = start;
00187     changelen = newdata.length();
00188 
00189     if(lastmsgsuccess) {
00190         vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyWrite,
00191                                                       *this, *this,
00192                                                       start, newdata.size(),
00193                                                       Property::read(), getDataType(),
00194                                                       oldvalue, getDataType(),
00195                                                       false);
00196 
00197 
00198         for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00199             (*i).second->notifyPropertyChange(*event);
00200         }
00201     }
00202 }
00203 
00204 void BufferedRemoteProperty::replace(const string& newdata, const string& newtype)
00205 {
00206     string olddatatype = Property::getDataType();
00207     string oldvalue;
00208     Property::read(oldvalue);
00209 
00210     Property::replace(newdata, newtype);
00211     changed = true;
00212     changestart = 0;
00213     changelen = getLength();
00214 
00215     if(lastmsgsuccess) {
00216         vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyReplace,
00217                                                       *this, *this,
00218                                                       newdata, newtype,
00219                                                       oldvalue, olddatatype,
00220                                                       false);
00221 
00222         for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00223             (*i).second->notifyPropertyChange(*event);
00224         }
00225     }
00226 }
00227 
00228 void BufferedRemoteProperty::flush()
00229 {
00230     if(changed) {
00231         LOG("BufferedRemoteProperty", 3, "flushing " << getURL().getString());
00232         if(changestart == 0 && changelen == getRawLength()) {
00233             pREF(Message*, m, new Message(),
00234                  rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:replace", true),
00235                       lastnonce = m->getNonce();
00236                       string s;
00237                       readRaw(s, 0, getRawLength());
00238                       m->insertField(-1, "data", s);
00239                       // if no type was supplied, assume the old cached one still is correct
00240                       m->insertField(-1, "datatype", getRawDataType());
00241                       sendMessage(m);
00242                      );
00243                 );
00244         } else {
00245             pREF(Message*, m, new Message(),
00246                  rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:write", true),
00247                       lastnonce = m->getNonce();
00248                       char x[16];
00249                       sprintf(x, "%i", changestart);
00250                       string s;
00251                       readRaw(s, changestart, changelen);
00252                       m->insertField(-1, "start", x);
00253                       m->insertField(-1, "data", s);
00254                       sendMessage(m);
00255                      );
00256                 );
00257         }
00258         changed = false;
00259     }
00260 }
00261 
00262 void BufferedRemoteProperty::flushAll()
00263 {
00264     for(set<BufferedRemoteProperty*>::iterator i = allbrps.begin(); i != allbrps.end(); i++) {
00265         (*i)->flush();
00266     }
00267 }
00268 
00269 void BufferedRemoteProperty::sendUpdateMessage(Message* m)
00270 {
00271     if(!(changed && lastmsgsuccess)) RemoteProperty::sendUpdateMessage(m);
00272 
00273     if(m->getNonce() == lastnonce
00274        && (m->getMethod() == "property:update"
00275            || m->getMethod() == "property:replace-update"))
00276     {
00277         try {
00278             m->getField("data");
00279             lastmsgsuccess = true;
00280         } catch(Message::NoSuchFieldError) {
00281             try {
00282                 m->getField("error");
00283                 lastmsgsuccess = false;
00284             } catch(Message::NoSuchFieldError) { }
00285         }
00286     }
00287 }
00288 
00289 void BufferedRemoteProperty::registerExtenders()
00290 {
00291     static bool done = false;
00292     if(! done) {
00293     RemoteSite::addRemoteObjectExtension(typeid(BufferedRemoteProperty).name(),
00294                                           &BufferedRemoteProperty::new_BufferedRemoteProperty);
00295     RemoteSite::addRemoteObjectExtension(typeid(RemoteProperty).name(),
00296                                           &BufferedRemoteProperty::new_BufferedRemoteProperty);
00297     RemoteSite::addRemoteObjectExtension(typeid(Property).name(),
00298                                           &BufferedRemoteProperty::new_BufferedRemoteProperty);
00299     RemoteSite::addRemoteObjectExtension("property:property",
00300                                           &BufferedRemoteProperty::new_BufferedRemoteProperty);
00301     done = true;
00302     }
00303 }

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