Urbi SDK Remote for C++  2.7.5
uvar-common.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2011, Gostai S.A.S.
00003  *
00004  * This software is provided "as is" without warranty of any kind,
00005  * either expressed or implied, including but not limited to the
00006  * implied warranties of fitness for a particular purpose.
00007  *
00008  * See the LICENSE file for more information.
00009  */
00010 
00012 
00013 #include <urbi/ucontext.hh>
00014 #include <urbi/uobject.hh>
00015 #include <urbi/uvalue.hh>
00016 #include <urbi/uvar.hh>
00017 
00018 GD_CATEGORY(Urbi.UVar);
00019 
00020 namespace urbi
00021 {
00022 
00023 
00024   /*-------.
00025   | UVar.  |
00026   `-------*/
00027   UVar::UVar(const std::string& varname, impl::UContextImpl* impl)
00028     : UContext(impl)
00029     , VAR_PROP_INIT
00030     , impl_(0)
00031     , name(varname)
00032   {
00033     __init();
00034   }
00035 
00036   UVar::UVar(UObject& obj, const std::string& varname, impl::UContextImpl* impl)
00037     : UContext(impl)
00038     , VAR_PROP_INIT
00039     , impl_(0)
00040     , name(obj.__name + '.' + varname)
00041   {
00042     __init();
00043   }
00044 
00045   UVar::UVar(const std::string& objname, const std::string& varname,
00046              impl::UContextImpl* impl)
00047     : UContext(impl)
00048     , VAR_PROP_INIT
00049     , impl_(0)
00050     , name(objname + '.' + varname)
00051   {
00052     __init();
00053   }
00054 
00055   UVar::UVar(const UVar& b)
00056   : UContext(b.ctx_)
00057   , VAR_PROP_INIT
00058   , impl_(0)
00059   , name (b.name)
00060   {
00061     __init();
00062   }
00063 
00064   void
00065   UVar::init(const std::string& varname, impl::UContextImpl* ctx)
00066   {
00067     GD_FINFO_DUMP("UVar.init %s", varname);
00068     if (varname == name && ctx == ctx_)
00069     {
00070       GD_FINFO_TRACE("Multiple UVar.init on %s @with same parameters, ignoring",
00071                      varname);
00072       return;
00073     }
00074     if (impl_)
00075     {
00076       GD_FINFO_TRACE("UVar.init rebinds from %s to %s", name, varname);
00077       unnotify();
00078       impl_->clean();
00079     }
00080     delete impl_;
00081     ctx_ = ctx;
00082     if (!ctx_)
00083       ctx_ = getCurrentContext();
00084     impl_ = 0;
00085     name = varname;
00086     __init();
00087   }
00088 
00089   bool
00090   UVar::invariant() const
00091   {
00092     if (vardata)
00093       return true;
00094     else
00095     {
00096       // FIXME: this special case should be put in doc.
00097       GD_FERROR ("Unable to locate variable %s in hashtable. "
00098                  "UVars being UObject attributes must be bound to be used "
00099                  "in UObject C++ code.  Use UBindVar.  "
00100                  "In any other case, this can be a memory problem. "
00101                  "Please report bug.",
00102                  name);
00103       return false;
00104     }
00105   }
00106 
00107   void
00108   UVar::__init()
00109   {
00110     owned = false;
00111     temp = false;
00112     rtp = RTP_DEFAULT;
00113     local = false;
00114     vardata = 0;
00115     if (!impl_)
00116     {
00117       impl_ = ctx_->getVarImpl();
00118     }
00119     impl_->initialize(this);
00120   }
00121 
00122   UVar::~UVar()
00123   {
00124     GD_FINFO_DUMP("~UVar %s", name);
00125     if (impl_)
00126     {
00127       unnotify();
00128       impl_->clean();
00129     }
00130     delete impl_;
00131   }
00132 
00133   void
00134   UVar::reset(ufloat n)
00135   {
00136     *this = n;
00137   }
00138 
00139   std::ostream&
00140   operator<< (std::ostream& o, const UVar& u)
00141   {
00142     return o << "UVar(\"" << u.get_name() << "\" = " << u.val() << ')';
00143   }
00144 
00145   UVar&
00146   uvalue_caster<UVar>::operator() (UValue& v)
00147   {
00148     if (v.type == DATA_VOID)
00149     {
00150       if (!v.storage)
00151         throw std::runtime_error("invalid cast to UVar from void value.");
00152       else
00153         return *((UVar*)v.storage);
00154     }
00155     if (v.type != DATA_STRING)
00156       throw std::runtime_error("invalid cast to UVar from non-string value.");
00157     UVar* var = new UVar(*v.stringValue);
00158     getCurrentContext()->addCleanup(var);
00159     var->set_temp(true);
00160     return *var;
00161   }
00162 
00163   UList&
00164   UList::operator=(UVar& v)
00165   {
00166     (*this) = (UList)v.val();
00167     return *this;
00168   }
00169 
00170   libport::utime_t
00171   UVar::timestamp() const
00172   {
00173     check();
00174     return impl_->timestamp();
00175   }
00176 
00177   void InputPort::init(UObject* owner, const std::string& name,
00178                        impl::UContextImpl* ctx)
00179   {
00180     UVar::init(owner->__name, name, ctx);
00181     impl_->setInputPort(true);
00182   }
00183   void InputPort::init(const std::string& owner, const std::string& name,
00184                        impl::UContextImpl* ctx)
00185   {
00186     UVar::init(owner, name, ctx);
00187     impl_->setInputPort(true);
00188   }
00189 } // namespace urbi