ModelParam.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Component/ModelParam.H"
00039
00040 #include "Component/ModelOptionDef.H"
00041 #include "Component/ParamClient.H"
00042 #include "Component/ParamMap.H"
00043 #include "Util/Assert.H"
00044 #include "Util/log.H"
00045 #include "rutz/demangle.h"
00046
00047 #include <ostream>
00048
00049 namespace
00050 {
00051 void initMutex(pthread_mutex_t* mut, int type)
00052 {
00053 pthread_mutexattr_t attr;
00054 if (0 != pthread_mutexattr_init(&attr))
00055 PLFATAL("pthread_mutexattr_init() failed");
00056
00057 if (0 != pthread_mutexattr_settype(&attr, type))
00058 {
00059 pthread_mutexattr_destroy(&attr);
00060 PLFATAL("pthread_mutexattr_settype() failed");
00061 }
00062
00063 if (0 != pthread_mutex_init(mut, &attr))
00064 {
00065 pthread_mutexattr_destroy(&attr);
00066 PLFATAL("pthread_mutex_init() failed");
00067 }
00068
00069 if (0 != pthread_mutexattr_destroy(&attr))
00070 PLERROR("pthread_mutexattr_destroy() failed");
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079 ModelParamAuxImpl::ModelParamAuxImpl(OptionedModelParam* self,
00080 const ModelOptionDef* def,
00081 ParamClient* client,
00082 const int flags,
00083 const std::type_info& valtype)
00084 :
00085 itsSelf(self),
00086 itsClient(client),
00087 itsOption(def),
00088 itsName(def->name),
00089 itsLocks(itsSelf->allowsOnlineChanges() ? new pthread_mutex_t[2] : 0),
00090 itsInCallback(false)
00091 {
00092 ASSERT(itsSelf != 0);
00093 ASSERT(itsClient != 0);
00094 ASSERT(itsOption != 0);
00095
00096 if (itsLocks != 0)
00097 {
00098 initMutex(&itsLocks[READLOCK], PTHREAD_MUTEX_RECURSIVE);
00099 initMutex(&itsLocks[WRITELOCK], PTHREAD_MUTEX_ERRORCHECK);
00100 }
00101
00102
00103 itsClient->registerOptionedParam(self, flags);
00104
00105 if (def->type.argtype == 0)
00106 LFATAL("ModelOptionDef '%s' had a null argtype type_info",
00107 def->name);
00108
00109 if (*def->type.argtype != valtype)
00110 LFATAL("the ModelParam '%s' "
00111 "being registered by '%s' has type '%s', "
00112 "but the corresponding ModelOptionDef has type '%s'",
00113 def->name,
00114 rutz::demangled_name(typeid(*client)),
00115 rutz::demangled_name(valtype),
00116 rutz::demangled_name(*def->type.argtype));
00117 }
00118
00119
00120 ModelParamAuxImpl::ModelParamAuxImpl(ModelParamBase* self,
00121 const std::string& nam,
00122 ParamClient* client)
00123 :
00124 itsSelf(self),
00125 itsClient(client),
00126 itsOption(0),
00127 itsName(nam),
00128 itsLocks(itsSelf->allowsOnlineChanges() ? new pthread_mutex_t[2] : 0),
00129 itsInCallback(false)
00130 {
00131 ASSERT(itsSelf != 0);
00132 ASSERT(itsClient != 0);
00133
00134 if (itsLocks != 0)
00135 {
00136 initMutex(&itsLocks[READLOCK], PTHREAD_MUTEX_RECURSIVE);
00137 initMutex(&itsLocks[WRITELOCK], PTHREAD_MUTEX_ERRORCHECK);
00138 }
00139
00140
00141 itsClient->registerParam(itsSelf);
00142 }
00143
00144
00145 ModelParamAuxImpl::~ModelParamAuxImpl()
00146 {
00147 ASSERT(itsClient != 0);
00148
00149
00150 itsClient->unregisterParam(itsSelf);
00151
00152 if (itsLocks != 0)
00153 {
00154 if (0 != pthread_mutex_destroy(&itsLocks[READLOCK]))
00155 PLERROR("pthread_mutex_destroy() failed for read lock");
00156 if (0 != pthread_mutex_destroy(&itsLocks[WRITELOCK]))
00157 PLERROR("pthread_mutex_destroy() failed for write lock");
00158 delete [] itsLocks;
00159 }
00160 }
00161
00162
00163 std::string ModelParamAuxImpl::getName() const
00164 {
00165 ASSERT(itsClient != 0);
00166
00167 return itsName;
00168 }
00169
00170
00171 const ModelOptionDef* ModelParamAuxImpl::getOptionDef() const
00172 {
00173 ASSERT(itsClient != 0);
00174
00175 ASSERT(itsOption != 0);
00176
00177 return itsOption;
00178 }
00179
00180
00181 void ModelParamAuxImpl::printout(std::ostream& s, const std::string& prefix) const
00182 {
00183 ASSERT(itsClient != 0);
00184
00185 s<<prefix<<": "<<itsName<<" = "<<itsSelf->getValString()<<std::endl;
00186 }
00187
00188
00189 void ModelParamAuxImpl::writeTo(ParamMap& pmap) const
00190 {
00191 ASSERT(itsClient != 0);
00192
00193 pmap.putStringParam(itsName, itsSelf->getValString());
00194 }
00195
00196
00197 void ModelParamAuxImpl::readFrom(const ParamMap& pmap, const bool noerr)
00198 {
00199 ASSERT(itsClient != 0);
00200
00201 std::string res = itsSelf->getValString();
00202 ParamMap::ReturnCode rc = pmap.queryStringParam(itsName, res);
00203 if (rc == ParamMap::CHANGED)
00204
00205 itsSelf->setValString(res);
00206
00207 if (noerr == false && rc == ParamMap::MISSING)
00208 LERROR("Cannot find parameter %s in ParamMap", itsName.c_str());
00209 }
00210
00211
00212 ParamClient::ChangeStatus
00213 ModelParamAuxImpl::sendChangedMessage(bool didchange)
00214 {
00215 if (itsInCallback)
00216 LFATAL("Oops! Got a re-entrant paramChanged() call for '%s' -- "
00217 "make sure you aren't re-setting %s from within its own "
00218 "paramChanged() callback, either directly with setVal(), "
00219 "or indirectly via exportOptions() or something similar",
00220 itsName.c_str(), itsName.c_str());
00221
00222 itsInCallback = true;
00223 ParamClient::ChangeStatus status = ParamClient::CHANGE_ACCEPTED;
00224 try {
00225 itsClient->paramChanged(itsSelf, didchange, &status);
00226 } catch (...) {
00227 itsInCallback = false;
00228 throw;
00229 }
00230 itsInCallback = false;
00231 return status;
00232 }
00233
00234
00235 const char* ModelParamAuxImpl::defaultValueOf(const ModelOptionDef* def)
00236 {
00237 return def->defval;
00238 }
00239
00240
00241
00242
00243
00244