celtool/stdpcimp.h
00001 /* 00002 Crystal Space Entity Layer 00003 Copyright (C) 2001 by Jorrit Tyberghein 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public 00016 License along with this library; if not, write to the Free 00017 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 #ifndef __CEL_CELTOOL_STDPC__ 00021 #define __CEL_CELTOOL_STDPC__ 00022 00023 #include "cstypes.h" 00024 #include "iutil/comp.h" 00025 #include "iutil/objreg.h" 00026 #include "ivaria/reporter.h" 00027 #include "csutil/csobject.h" 00028 #include "csutil/scf.h" 00029 #include "csutil/scf_implementation.h" 00030 #include "csutil/refarr.h" 00031 #include "csutil/weakref.h" 00032 00033 #include "celtool/celtoolextern.h" 00034 00035 #include "physicallayer/propchg.h" 00036 #include "physicallayer/propclas.h" 00037 #include "physicallayer/propfact.h" 00038 #include "physicallayer/pl.h" 00039 #include "physicallayer/messaging.h" 00040 00041 struct iCelEntity; 00042 struct iObjectRegistry; 00043 00044 00045 struct Property 00046 { 00047 csStringID id; 00048 celDataType datatype; 00049 bool readonly; 00050 const char* desc; 00051 Property () : id (csInvalidStringID) { } 00052 }; 00053 00059 struct PropertyHolder 00060 { 00061 Property* properties; 00062 size_t propertycount; 00063 // Set to true if we have done an action. 00064 bool actions_done; 00065 // The mask that we will use to listen for messages. 00066 csString mask; 00067 00072 csHash<int, csStringID> constants; 00073 00078 csHash<int, csStringID> new_constants; 00079 00080 PropertyHolder () : properties (0), propertycount (0), actions_done (false) 00081 { } 00082 ~PropertyHolder () { delete[] properties; } 00083 void SetCount (int cnt) 00084 { 00085 if (properties) return; 00086 propertycount = cnt; 00087 properties = new Property[cnt]; 00088 } 00089 }; 00090 00096 class CEL_CELTOOL_EXPORT celPcCommon 00097 : public scfImplementation4<celPcCommon, iCelPropertyClass, iCelTimerListener, 00098 iMessageSender,iMessageReceiver> 00099 { 00100 private: 00101 csRefArray<iCelPropertyChangeCallback> callbacks; 00102 // This flag is true if we currently don't know the state of 00103 // the sibling property classes (property classes in the same 00104 // entity). It is set to true by PropertyClassesHaveChanged() 00105 // and cleared by HavePropertyClassesChanged(). 00106 bool propclasses_dirty; 00107 csString tag; 00108 // the name of the property class stored in the iObject 00109 csObject csobj; 00110 00111 static csStringID id_tag; 00112 static csStringID id_name; 00113 static csStringID id_value; 00114 00115 protected: 00116 iCelEntity* entity; 00117 iObjectRegistry* object_reg; 00118 csWeakRef<iCelPlLayer> pl; 00119 00120 protected: 00121 void FirePropertyChangeCallback (int propertyId); 00122 00126 void SetActionMask (const char* mask); 00127 00131 void AddAction (int idx, const char* id) 00132 { 00133 propholder->actions_done = true; 00134 propholder->constants.Put (pl->FetchStringID (id), idx); 00135 csString newid = propholder->mask; 00136 CS_ASSERT (newid.Length () > 0); 00137 newid += id; 00138 propholder->new_constants.Put (pl->FetchStringID (newid), idx); 00139 } 00140 00152 void AddProperty (size_t idx, const char* id, 00153 celDataType type, bool readonly, const char* desc, 00154 void* prop) 00155 { 00156 // return if an invalid index was specified 00157 if (idx >= propholder->propertycount) 00158 { 00159 Error ( 00160 "celPcCommon::AddProperty out of bounds %zu >= %zu!", 00161 idx, propholder->propertycount); 00162 return; 00163 } 00164 if (propdata == 0) 00165 { 00166 propdata = new void* [propholder->propertycount]; 00167 } 00168 Property& pr = propholder->properties[idx]; 00169 if (pr.id == csInvalidStringID) 00170 { 00171 pr.id = pl->FetchStringID (id); 00172 pr.datatype = type; 00173 pr.readonly = readonly; 00174 pr.desc = desc; 00175 propholder->constants.Put (pr.id, (int)idx); 00176 } 00177 propdata[idx] = prop; 00178 } 00179 00180 void** propdata; 00181 PropertyHolder* propholder; 00182 00183 private: 00184 template <class T> 00185 bool SetPropertyTemplated (csStringID propertyId, T l, 00186 celDataType type); 00187 template <class T> 00188 T GetPropertyTemplated (csStringID propertyId, celDataType type); 00189 template <class T> 00190 bool GetPropertyTemplated (csStringID propertyId, celDataType type, T& v); 00191 00192 public: 00193 celPcCommon (iObjectRegistry* object_reg); 00194 virtual ~celPcCommon (); 00195 00196 bool HavePropertyClassesChanged () 00197 { 00198 if (!propclasses_dirty) return false; 00199 propclasses_dirty = false; 00200 return true; 00201 } 00202 00204 bool Error (char const *desc, ...) const; 00206 bool Warning (char const *desc, ...) const; 00208 bool Bug (char const *desc, ...) const; 00210 bool Notify (char const *desc, ...) const; 00211 00212 static const char* GetTypeName (celDataType type) 00213 { 00214 switch (type) 00215 { 00216 case CEL_DATA_STRING: return "string"; 00217 case CEL_DATA_LONG: return "long"; 00218 case CEL_DATA_BOOL: return "bool"; 00219 case CEL_DATA_FLOAT: return "float"; 00220 case CEL_DATA_VECTOR2: return "vector2"; 00221 case CEL_DATA_VECTOR3: return "vector3"; 00222 case CEL_DATA_VECTOR4: return "vector4"; 00223 case CEL_DATA_COLOR: return "color"; 00224 case CEL_DATA_COLOR4: return "color4"; 00225 case CEL_DATA_PCLASS: return "pc"; 00226 default: return "?"; 00227 } 00228 } 00229 static bool IsTypeCompatible (celDataType wanted, celDataType have) 00230 { 00231 if (wanted == have) return true; 00232 if (wanted == CEL_DATA_FLOAT && have == CEL_DATA_LONG) return true; 00233 if (wanted == CEL_DATA_LONG && have == CEL_DATA_FLOAT) return true; 00234 if (wanted == CEL_DATA_BOOL && have == CEL_DATA_LONG) return true; 00235 return false; 00236 } 00237 00238 bool CheckTypeCompatible (celDataType wanted, celDataType have, 00239 csStringID id) 00240 { 00241 if (!IsTypeCompatible (have, wanted)) 00242 { 00243 return Error ( 00244 "Incompatible type for parameter '%s' for property class '%s/%s' and entity '%s'! Expected '%s'!\n", 00245 pl->FetchString (id), GetName (), GetTag (), GetEntity ()->GetName (), 00246 GetTypeName (wanted)); 00247 } 00248 return true; 00249 } 00250 00251 bool CheckData (const celData* data, csStringID id, bool usedef) 00252 { 00253 if (!data && !usedef) 00254 { 00255 return Error ( 00256 "Missing parameter '%s' for property class '%s/%s' and entity '%s'!\n", 00257 pl->FetchString (id), GetName (), GetTag (), GetEntity ()->GetName ()); 00258 return false; 00259 } 00260 return true; 00261 } 00262 00263 bool ParExists (celDataType type, iCelParameterBlock* params, csStringID id) 00264 { 00265 if (!params) return false; 00266 const celData* data = params->GetParameter (id); 00267 if (!data) return false; 00268 return data->type == type; 00269 } 00270 00271 bool Fetch (csString& var, iCelParameterBlock* params, csStringID id, 00272 bool use_def = false, const char* def = "") 00273 { 00274 if (!params) return false; 00275 const celData* data = params->GetParameter (id); 00276 if (!CheckData (data, id, use_def)) return false; 00277 if (!data && use_def) { var = def; return true; } 00278 if (!CheckTypeCompatible (CEL_DATA_STRING, data->type, id)) return false; 00279 var = data->value.s->GetData (); 00280 return true; 00281 } 00282 bool Fetch (long& var, iCelParameterBlock* params, csStringID id, 00283 bool use_def = false, long def = 0) 00284 { 00285 if (!params) return false; 00286 const celData* data = params->GetParameter (id); 00287 if (!CheckData (data, id, use_def)) return false; 00288 if (!data && use_def) { var = def; return true; } 00289 if (!CheckTypeCompatible (CEL_DATA_LONG, data->type, id)) return false; 00290 if (data->type == CEL_DATA_LONG) var = data->value.l; 00291 else var = (long)data->value.f; 00292 return true; 00293 } 00294 bool Fetch (float& var, iCelParameterBlock* params, csStringID id, 00295 bool use_def = false, float def = 0.0f) 00296 { 00297 if (!params) return false; 00298 const celData* data = params->GetParameter (id); 00299 if (!CheckData (data, id, use_def)) return false; 00300 if (!data && use_def) { var = def; return true; } 00301 if (!CheckTypeCompatible (CEL_DATA_FLOAT, data->type, id)) return false; 00302 if (data->type == CEL_DATA_LONG) var = float (data->value.l); 00303 else var = data->value.f; 00304 return true; 00305 } 00306 bool Fetch (bool& var, iCelParameterBlock* params, csStringID id, 00307 bool use_def = false, bool def = false) 00308 { 00309 if (!params) return false; 00310 const celData* data = params->GetParameter (id); 00311 if (!CheckData (data, id, use_def)) return false; 00312 if (!data && use_def) { var = def; return true; } 00313 if (!CheckTypeCompatible (CEL_DATA_BOOL, data->type, id)) return false; 00314 if (data->type == CEL_DATA_BOOL) var = data->value.bo; 00315 else var = (bool)data->value.l; 00316 return true; 00317 } 00318 bool Fetch (iCelPropertyClass*& var, iCelParameterBlock* params, csStringID id, 00319 bool use_def = false, iCelPropertyClass* def = 0) 00320 { 00321 if (!params) return false; 00322 const celData* data = params->GetParameter (id); 00323 if (!CheckData (data, id, use_def)) return false; 00324 if (!data && use_def) { var = def; return true; } 00325 if (!CheckTypeCompatible (CEL_DATA_PCLASS, data->type, id)) return false; 00326 var = data->value.pc; 00327 return true; 00328 } 00329 bool Fetch (csVector2& var, iCelParameterBlock* params, csStringID id, 00330 bool use_def = false, csVector2 def = csVector2 (0, 0)) 00331 { 00332 if (!params) return false; 00333 const celData* data = params->GetParameter (id); 00334 if (!CheckData (data, id, use_def)) return false; 00335 if (!data && use_def) { var = def; return true; } 00336 if (!CheckTypeCompatible (CEL_DATA_VECTOR2, data->type, id)) return false; 00337 var.Set (data->value.v.x, data->value.v.y); 00338 return true; 00339 } 00340 bool Fetch (csVector3& var, iCelParameterBlock* params, csStringID id, 00341 bool use_def = false, csVector3 def = csVector3 (0, 0, 0)) 00342 { 00343 if (!params) return false; 00344 const celData* data = params->GetParameter (id); 00345 if (!CheckData (data, id, use_def)) return false; 00346 if (!data && use_def) { var = def; return true; } 00347 if (!CheckTypeCompatible (CEL_DATA_VECTOR3, data->type, id)) return false; 00348 var.Set (data->value.v.x, data->value.v.y, data->value.v.z); 00349 return true; 00350 } 00351 bool Fetch (csVector4& var, iCelParameterBlock* params, csStringID id, 00352 bool use_def = false, csVector4 def = csVector4 (0, 0, 0, 0)) 00353 { 00354 if (!params) return false; 00355 const celData* data = params->GetParameter (id); 00356 if (!CheckData (data, id, use_def)) return false; 00357 if (!data && use_def) { var = def; return true; } 00358 if (!CheckTypeCompatible (CEL_DATA_VECTOR4, data->type, id)) return false; 00359 var.Set (data->value.v.x, data->value.v.y, data->value.v.z, data->value.v.w); 00360 return true; 00361 } 00362 bool Fetch (csColor& var, iCelParameterBlock* params, csStringID id, 00363 bool use_def = false, csColor def = csColor (0, 0, 0)) 00364 { 00365 if (!params) return false; 00366 const celData* data = params->GetParameter (id); 00367 if (!CheckData (data, id, use_def)) return false; 00368 if (!data && use_def) { var = def; return true; } 00369 if (!CheckTypeCompatible (CEL_DATA_COLOR, data->type, id)) return false; 00370 var.Set (data->value.col.red, data->value.col.green, data->value.col.blue); 00371 return true; 00372 } 00373 bool Fetch (csColor4& var, iCelParameterBlock* params, csStringID id, 00374 bool use_def = false, csColor4 def = csColor4 (0, 0, 0, 0)) 00375 { 00376 if (!params) return false; 00377 const celData* data = params->GetParameter (id); 00378 if (!CheckData (data, id, use_def)) return false; 00379 if (!data && use_def) { var = def; return true; } 00380 if (!CheckTypeCompatible (CEL_DATA_COLOR4, data->type, id)) return false; 00381 var.Set (data->value.col.red, data->value.col.green, data->value.col.blue, 00382 data->value.col.alpha); 00383 return true; 00384 } 00385 00386 virtual void SetTag (const char* tagname); 00387 virtual const char* GetTag () const { return tag; } 00388 00389 virtual const char* GetName () const; 00390 virtual void SetName (const char* pcname); 00391 00392 iObject *QueryObject (); 00393 00394 virtual iCelEntity* GetEntity () { return entity; } 00395 virtual void SetEntity (iCelEntity* entity); 00396 virtual bool AddPropertyChangeCallback (iCelPropertyChangeCallback* cb); 00397 virtual bool RemovePropertyChangeCallback ( 00398 iCelPropertyChangeCallback* cb); 00399 00400 virtual bool SetPropertyIndexed (int, long) { return false; } 00401 virtual bool SetPropertyIndexed (int, float) { return false; } 00402 virtual bool SetPropertyIndexed (int, bool) { return false; } 00403 virtual bool SetPropertyIndexed (int, const char*) { return false; } 00404 virtual bool SetPropertyIndexed (int, const csVector2&) { return false; } 00405 virtual bool SetPropertyIndexed (int, const csVector3&) { return false; } 00406 virtual bool SetPropertyIndexed (int, const csColor&) { return false; } 00407 virtual bool SetPropertyIndexed (int, iCelPropertyClass* pclass) 00408 { return false; } 00409 virtual bool SetPropertyIndexed (int, iCelEntity* entity) { return false; } 00410 virtual bool SetPropertyIndexed (int, iBase* ibase) { return false; } 00411 00412 virtual bool SetProperty (csStringID, long); 00413 virtual bool SetProperty (csStringID, float); 00414 virtual bool SetProperty (csStringID, bool); 00415 virtual bool SetProperty (csStringID, const char*); 00416 virtual bool SetProperty (csStringID, const csVector2&); 00417 virtual bool SetProperty (csStringID, const csVector3&); 00418 virtual bool SetProperty (csStringID, const csColor&); 00419 virtual bool SetProperty (csStringID, iCelPropertyClass* pclass); 00420 virtual bool SetProperty (csStringID, iCelEntity* entity); 00421 virtual bool SetProperty (csStringID, iBase* ibase); 00422 00423 virtual bool GetPropertyIndexed (int, long& l) { return false; } 00424 virtual bool GetPropertyIndexed (int, float& f) { return false; } 00425 virtual bool GetPropertyIndexed (int, bool& b) { return false; } 00426 virtual bool GetPropertyIndexed (int, const char*&) { return false; } 00427 virtual bool GetPropertyIndexed (int, csVector2&) { return false; } 00428 virtual bool GetPropertyIndexed (int, csVector3&) { return false; } 00429 virtual bool GetPropertyIndexed (int, csColor&) { return false; } 00430 virtual bool GetPropertyIndexed (int, iCelPropertyClass*&) { return false; } 00431 virtual bool GetPropertyIndexed (int, iCelEntity*&) { return false; } 00432 virtual bool GetPropertyIndexed (int, iBase*&) { return false; } 00433 00434 virtual long GetPropertyLongByID (csStringID); 00435 virtual float GetPropertyFloatByID (csStringID); 00436 virtual bool GetPropertyBoolByID (csStringID); 00437 virtual const char* GetPropertyStringByID (csStringID); 00438 virtual bool GetPropertyVectorByID (csStringID, csVector2&); 00439 virtual bool GetPropertyVectorByID (csStringID, csVector3&); 00440 virtual bool GetPropertyColorByID (csStringID, csColor&); 00441 virtual iCelPropertyClass* GetPropertyPClassByID (csStringID); 00442 virtual iCelEntity* GetPropertyEntityByID (csStringID); 00443 virtual iBase* GetPropertyIBaseByID (csStringID); 00444 00445 virtual bool PerformAction (csStringID, iCelParameterBlock*, celData& ret); 00446 virtual bool PerformActionIndexed (int, iCelParameterBlock*, celData& ret) 00447 { return false; } 00448 virtual const char* GetPropertyOrActionDescription (csStringID); 00449 virtual size_t GetPropertyAndActionCount (); 00450 virtual csStringID GetPropertyOrActionID (size_t); 00451 virtual void PropertyClassesHaveChanged () 00452 { 00453 propclasses_dirty = true; 00454 } 00455 virtual celDataType GetPropertyOrActionType (csStringID); 00456 virtual bool IsPropertyReadOnly (csStringID); 00457 00458 virtual csPtr<iCelDataBuffer> GetPersistentData ( 00459 celPersistenceType persistence_type) 00460 { return 0; } 00461 virtual celPersistenceResult SetPersistentData (csTicks data_time, 00462 iCelDataBuffer* data, celPersistenceType persistence_type) 00463 { return CEL_PERSIST_RESULT_OK; }; 00464 00465 virtual iCelPositionInfo* QueryPositionInfo () { return 0; } 00466 virtual void Activate () { } 00467 virtual void Deactivate () { } 00468 00469 virtual void MarkBaseline () { } 00470 virtual bool IsModifiedSinceBaseline () const { return false; } 00471 virtual void SaveModifications (iCelCompactDataBufferWriter* buf, iStringSet* strings) { } 00472 virtual void RestoreModifications (iCelCompactDataBufferReader* buf, 00473 const csHash<csString,csStringID>& strings) { } 00474 00475 // --- For iCelTimerListener ----------------------------------------- 00476 virtual void TickEveryFrame () { } 00477 virtual void TickOnce () { } 00478 00479 // --- For iMessageSender -------------------------------------------- 00480 virtual void MessageDispatcherRemoved (iMessageDispatcher* dispatcher) { } 00481 00482 // --- For iMessageReceiver ------------------------------------------ 00483 virtual bool ReceiveMessage (csStringID msg_id, iMessageSender* sender, 00484 celData& ret, iCelParameterBlock* params); 00485 }; 00486 00487 #endif // __CEL_CELTOOL_STDPC__ 00488
Generated for CEL: Crystal Entity Layer 2.1 by doxygen 1.6.1
