INOS
cinoscontainer.h
Go to the documentation of this file.
1//******************************************************************************
28//******************************************************************************
29//
30#ifndef INC_CINOSCONTAINER_H
31#define INC_CINOSCONTAINER_H
32//
33//------------------------------------------------------------------------------
34// defines
35//------------------------------------------------------------------------------
36//
37// --- container errors ---------------------------------------------------------
38//
39#define ER_INOS_CONTAINER_OK 0x00000000 // command ok
40#define ER_INOS_CONTAINER_REJECTED 0x00000001 // command rejected
41#define ER_INOS_CONTAINER_FAILED 0x00000002 // command failed
42#define ER_INOS_CONTAINER_TYPE_UNKNOWN 0x00000003 // command type unknown
43#define ER_INOS_CONTAINER_CHECK_FAILED 0x00000004 // command check failed
44//
45//------------------------------------------------------------------------------
46// includes
47//------------------------------------------------------------------------------
48//
49// system
50#include <inos.h>
51#include <inos_lib.h>
52#include <cinoseventlogger.h>
53//
54// C++
55//
56// project
57//
58//------------------------------------------------------------------------------
59// class definition
60//------------------------------------------------------------------------------
61//
103template <class T> class CINOSContainer
104{
105 //--- user interface ---------------------------------------------------
106
107 public:
108
112 CINOSContainer(const char* apName, const char* apElementBases);
113 CINOSContainer(const char* apName, const char* apElementBases, void* apParent);
116
118 void SetParent(void* apParent);
121 void SetBase(const char* apElementBases);
123 void SetName(const char* apName) {
124 inos_strncpy(m_cName, apName, sizeof(m_cName));
125 }
126
128 uint32 Create(const char* apName);
130 uint32 Create(const char* apName, const char* apType);
132 uint32 Create(const char* apName, const char* apType, const char* apParam);
134 uint32 Destroy(const char* apName);
135
137 uint32 Check(const char* apType, const char* apParam);
138
140 virtual void Add(T* apEntity);
142 virtual void Remove(T* apEntity, bool abDelete=true);
143
145 virtual T* Find(const char* apName);
147 virtual T* GetAt(uint32 auIndex);
149 virtual uint32 GetNumber();
150
151 typedef int(*tForEach)(T&, void *);
152 virtual void ForEach( tForEach cond, void *args );
153 template <typename F>
154 void ForEach( F cond );
155
157 void RegisterHook(void* apObject, void* apMethod);
158
160 CINCOObject* GetRegister(bool abLight=false);
161
162 //--- internals --------------------------------------------------------
163
164 // internal methods
165 private :
166
167 // protected members
168 protected:
170 char m_cName[32];
172 char m_cBase[256];
180 TINOSNameBalancedBinaryTree<T>* m_pEntities;
182 CINCOObject* m_pRegister;
184 CINCOObject* m_pCmd;
186 CINCOObject* m_pEntity;
188 CINCOObject* m_pProp;
190 int16 m_iOrder;
191
193 char m_ceName[64];
195 char m_ceType[32];
197 char m_ceParam[256];
198
199 // allow dynamic object handling (new/delete)
201};
202
203// allow dynamic object handling (new/delete)
205
206//------------------------------------------------------------------------------
207// container entity registration
208//------------------------------------------------------------------------------
209
210typedef void* (*TCreateEntity)(const char* apName, const char* apParam);
211typedef bool (*TCheckCheckTarget)(const char* apParam);
212
220{
221 //--- internals --------------------------------------------------------
222
223 friend class CINOSHwTarget;
224
225 // private members
226 private:
227 // pointer to the first registered entity
228 static CINOSContainerEntityRegister* m_pFirst;
229 // pointer to the next entity
231 // create function of the entity
232 TCreateEntity m_pCreate;
233 // check function, if != 0 -> the entity is only created if 'CheckTarget' returns true
234 TCheckCheckTarget m_pCheck;
235 // entity type name
236 const char* m_pType;
237 // entity base name
238 const char* m_pBase;
239
240 //--- user interface ---------------------------------------------------
241
242 public:
243 // register a new entity type
244 CINOSContainerEntityRegister(TCreateEntity apFunction,
245 const char* apType, const char* apBase, TCheckCheckTarget apCheck=0);
246 // create and return and instance
247 static void* GetInstance(const char* apName, const char* apType,
248 const char* apParam, const char* apAllowedBases = NULL);
249 // check if instance of given type can be created
250 static uint32 Check(const char* apType, const char* apParam, const char* apAllowedBases = NULL);
251};
252
253//------------------------------------------------------------------------------
254// container inco object
255//------------------------------------------------------------------------------
256
257class CINCOConObject : public CINCOObject
258{
259 char m_cName[128];
260 bool m_bIsFolder;
261 public:
262 CINCOConObject(char* apName, void* apData, bool abIsFolder)
263 : CINCOObject(&m_cName[0], apData, 0, defCharObjectOwnBitmap),
264 m_bIsFolder(abIsFolder)
265 {
266 // copy name
267 inos_strncpy(m_cName, apName, sizeof(m_cName));
268 }
269
270 // is this just a folder object created by a container
271 virtual bool IsContainerFolder() { return m_bIsFolder; };
273};
274
275//------------------------------------------------------------------------------
276// class implementation
277//------------------------------------------------------------------------------
278//
279template <class T> CINOSContainer<T>::CINOSContainer(const char* apName,
280 const char* apElementBases)
281 : m_pCmd(NULL),
282 m_pEntity(NULL),
283 m_pProp(NULL)
284{
285 // init members
286 inos_strncpy(m_cName, apName, sizeof(m_cName));
287 inos_strncpy(m_cBase, apElementBases, sizeof(m_cBase));
288 m_pParent = 0;
289 m_pHookObj = 0;
290 m_pHookMtd = 0;
291 m_pRegister = 0;
292 m_iOrder = 0;
293 m_ceName[0] = 0;
294 m_ceType[0] = 0;
295 m_ceParam[0] = 0;
296 // create binary tree
297 m_pEntities = new TINOSNameBalancedBinaryTree<T>;
298}
299
300template <class T> CINOSContainer<T>::CINOSContainer(const char* apName,
301 const char* apElementBases, void* apParent)
302 : m_pCmd(NULL),
303 m_pEntity(NULL),
304 m_pProp(NULL)
305{
306 // init members
307 inos_strncpy(m_cName, apName, sizeof(m_cName));
308 inos_strncpy(m_cBase, apElementBases, sizeof(m_cBase));
309 m_pParent = apParent;
310 m_pHookObj = 0;
311 m_pHookMtd = 0;
312 m_pRegister = 0;
313 m_iOrder = 0;
314 m_ceName[0] = 0;
315 m_ceType[0] = 0;
316 m_ceParam[0] = 0;
317 // create binary tree
318 m_pEntities = new TINOSNameBalancedBinaryTree<T>;
319}
320
322{
323 // we remove each entity one by one to ensure that any intermediate
324 // CINCOObject, that may have been created, will be destroyed as well.
325 // This is the case e.g. when the name of the entity is "Parent.Name"
326 T* entity = m_pEntities->GetAt(0);
327 while( entity ) {
328 Destroy(entity->GetName());
329 entity = m_pEntities->GetAt(0);
330 }
331 // destroy binary tree
332 delete m_pEntities;
333 // delete inco registration
334 if (m_pRegister){
335 // do it
336 delete m_pRegister;
337 }
338}
339
340template <class T> void CINOSContainer<T>::SetParent(void* apParent)
341{
342 // set parent pointer
343 m_pParent = apParent;
344}
345
346template <class T> void CINOSContainer<T>::SetBase(const char* apElementBases)
347{
348 // set allowed element bases
349 inos_strncpy(m_cBase, apElementBases, sizeof(m_cBase));
350}
351
352template <class T> void CINOSContainer<T>::Add(T* apEntity)
353{
354 // and add it to inco tree
355 ASSERT_ALWAYS(m_pEntity && "INCOObject not created. Did you forget to call GetRegister?");
356 CINCOObject* obj = m_pEntity;
357 char* name = (char *) apEntity->GetName();
358 do {
359 // get '.' in name
360 char* p = strchr(name, '.');
361 // did we find one
362 if (p) {
363 // yes -> clear '.'
364 *p++ = 0;
365
366 // obj already created ?
367 CINCOItem* tmp = obj->Find(name);
368 if (tmp && (tmp->GetType() == defType_Object)){
369 // yes
370 obj = (CINCOObject*) tmp;
371 }
372 else{
373 // no -> create one
374 CINCOConObject* o = new CINCOConObject(name, apEntity, true);
375 obj->Add(o, m_iOrder++);
376 obj = o;
377 }
378 *(p-1) = '.';
379 name = p;
380 }
381 else {
382 // check if folder already available
383 ASSERT_ALWAYS(obj->Find(name) == NULL && "It is not allowed to add a container element with a name that is already used as parent of another container element.")
384
385 // add entity registration to inco tree
386 CINCOObject* o = new CINCOConObject(name, apEntity, false);
387 obj->Add(o, m_iOrder++);
388 apEntity->GetRegister(o);
389
390 // add entity to tree
391 m_pEntities->Add(apEntity);
392 return;
393 }
394
395 } while (1);
396}
397
398template <class T> void CINOSContainer<T>::Remove(T* apEntity, bool abDelete)
399{
400 // get entity name
401 char cName[256];
402 inos_strncpy(cName, apEntity->GetName(), sizeof(cName));
403 char* p = strrchr(cName, '.');
404 if (p) {
405 // hierachically organised
406 bool bDone=false;
407 do {
408 *p=0;
409 CINCOObject* obj = (CINCOObject *) m_pEntity->Find(cName);
410 if (obj){
411 CINCOObject* sub = (CINCOObject *) obj->Find(++p);
412 bool bDelete = sub && sub->IsContainerFolder()
413 && sub->GetBinaryTree()->GetItemsInContainer() == 0;
414 // remove entity from obj
415 obj->Remove(p, bDelete);
416 // check if still member left on this level
417 if (obj->GetBinaryTree()->mItemsInContainer){
418 // yes -> done
419 bDone = true;
420 } // end if
421 else {
422 // no -> go further
423 p = strrchr(cName, '.');
424 if (!p) {
425 // no more levels -> remove it direct from 'Entity' folder
426 m_pEntity->Remove(cName);
427 // done
428 bDone = true;
429 } // end if
430 } // end else
431 } // end if
432 else {
433 // not found -> done (should not occur)
434 bDone = true;
435 } // end else
436 } while (!bDone);
437 } // end if
438 else {
439 // flat -> remove entity from 'Entity' folder
440 m_pEntity->Remove((char *) apEntity->GetName(), false);
441 } // end else
442
443 // remove entity from tree
444 m_pEntities->Remove(apEntity, abDelete);
445}
446
447template <class T> T* CINOSContainer<T>::Find(const char* apName)
448{
449 // find entity in tree
450 return m_pEntities->Find(apName);
451}
452
453template <class T> T* CINOSContainer<T>::GetAt(uint32 auIndex)
454{
455 // find entity in tree
456 return m_pEntities->GetAt(auIndex);
457}
458
459template <class T> uint32 CINOSContainer<T>::GetNumber()
460{
461 // find entity in tree
462 return (uint32)m_pEntities->GetItemsInContainer();
463}
464
465template <class T> void CINOSContainer<T>::ForEach( tForEach cond, void *args )
466{
467 m_pEntities->ForEach(cond, args);
468}
469
470template <class T> template <typename F> void CINOSContainer<T>::ForEach( F cond )
471{
472 m_pEntities->ForEach(cond);
473}
474
475template <class T> void CINOSContainer<T>::RegisterHook(void* apObject, void* apMethod)
476{
477 // set members
478 m_pHookObj = apObject;
479 m_pHookMtd = apMethod;
480}
481
482template <class T> uint32 CINOSContainer<T>::Create(const char* apName)
483{
484 // call main create with base type (only makes sense if we have a single base and it also names a type)
485 return Create(apName, m_cBase);
486
487 // end CINOSContainer::Create
488}
489
490template <class T> uint32 CINOSContainer<T>::Create(const char* apName,
491 const char* apType)
492{
493 // call main create
494 return Create(apName, apType, 0);
495
496 // end CINOSContainer::Create
497}
498
499template <class T> uint32 CINOSContainer<T>::Create(const char* apName,
500 const char* apType, const char* apParam)
501{
502 // check name pointer
503 if (!apName || !*apName){
504 // no valid name
505 return ER_INOS_CONTAINER_FAILED;
506 }
507
508 // check if non destructive requested
509 bool bNonDest=false;
510 if (apParam && strstr(apParam, "NoD")){
511 bNonDest=true;
512 } // end if
513
514 // try to get entity
515 T* ent = m_pEntities->Find(apName);
516 // check name
517 if (ent){
518 // entity with this name already exists -> destruction allowed ?
519 if (!bNonDest){
520 // yes -> destroy it
521 Destroy(apName);
522 } // end if
523 else {
524 // we have already such an entity an non destruction requested
525 // just return ok
526 return 0;
527 } // end else
528 } // end if
529
530 // try to create entity
531 ent = (T*) CINOSContainerEntityRegister::GetInstance(apName, apType,
532 apParam, m_cBase);
533 // did we get one ?
534 if (ent){
535 // yes -> add it to the tree
536 Add(ent);
537 // call post create method
538 ent->PostCreate(m_pParent);
539 // check if we have to call hook
540 if (m_pHookObj && m_pHookMtd){
541 // yes -> call it
542 INOSCallClassMember(m_pHookObj, m_pHookMtd, (uintptr) ent);
543 } // end if
544 // ok
545 return 0;
546 } // end if
547 else {
548 // no -> failed
549 return ER_INOS_CONTAINER_FAILED;
550 } // end if
551
552 // end CINOSContainer::Create
553}
554
555template <class T> uint32 CINOSContainer<T>::Destroy(const char* apName)
556{
557 // check name pointer
558 if (!apName || !*apName){
559 // no valid name
560 return ER_INOS_CONTAINER_FAILED;
561 }
562
563 // check if single or multiple
564 T* ent = m_pEntities->Find(apName);
565 if (ent) {
566 // single
567 bool bDeleteSelf = false;
568 if (!ent->PreDestroy(bDeleteSelf)){
569 //destroy not allowed
570 return ER_INOS_CONTAINER_REJECTED;
571 }
572 // and remove it but
573 Remove(ent, !bDeleteSelf);
574 } // end if
575 else {
576 // multiple
577 bool bDone = false;
578 uint32 l = (uint32)strlen(apName);
579 uint32 i = 0;
580 uint32 n = 0;
581 do {
582 // get container entry
583 T* ent = m_pEntities->GetAt(i);
584 if (ent) {
585 if (strncmp(apName, ent->GetName(), l)==0){
586 // we found one
587 n++;
588 bool bDeleteSelf = false;
589 if (!ent->PreDestroy(bDeleteSelf)){
590 //destroy not allowed
591 return ER_INOS_CONTAINER_REJECTED;
592 } // end if
593 // and remove it but
594 Remove(ent, !bDeleteSelf);
595 // reset index
596 i = 0;
597 } // end if
598 else {
599 // increment index
600 i++;
601 } // end else
602 } // end if
603 else {
604 // no more entries
605 bDone = true;
606 } // end else
607
608 } while (!bDone);
609
610 // check name
611 if (!n){
612 // no entry with this name -> return failed
613 return ER_INOS_CONTAINER_FAILED;
614 } // end if
615 } // end else
616
617 // ok
618 return 0;
619
620 // end CINOSContainer::Destroy
621}
622
623//------------------------------------------------------------------------------
624//
625template <class T> uint32 CINOSContainer<T>::Check(const char* apType, const char* apParam)
626{
627 return CINOSContainerEntityRegister::Check(apType, apParam, m_cBase);
628
629 // end CINOSContainer::Check
630}
631
632//------------------------------------------------------------------------------
633//
634template <class T> CINCOObject* CINOSContainer<T>::GetRegister(bool abLight)
635{
636 // did we create inco object already ?
637 if (m_pRegister){
638 // yes -> return pointer
639 return m_pRegister;
640 } // end if
641
642 // create main folder
643 m_pRegister = new CINCOObject((char*) &m_cName[0], this, 0, defCharObjectOwnBitmap);
644 m_pRegister->Add(new CINCOuint32((char*) &m_cName[0], &m_pEntities->mItemsInContainer,
645 0,0,"", defCharShowDec | defCharReadOnly));
646 // light registration (without Cmd and Entity folder)
647 if (!abLight) {
648 // no -> add entity folder
649 m_pEntity = new CINCOObject("Entity", 0);
650 m_pRegister->Add(m_pEntity);
651 // and add cmd folder
652 m_pCmd = new CINCOObject("Cmd", 0);
653 m_pRegister->Add(m_pCmd);
654
655 // create entity
656 CINCOObject* cmdCreate = new CINCOObject("Create", 0);
657 cmdCreate->Add(new CINCOProcedure(REG_TYP_CLS_FCT_NAME_OVLD(Create,
658 CINOSContainer<T>, this, uint32, Create,(const char*))), 0);
659 cmdCreate->Add(new CINCOstring("Name", m_ceName, sizeof(m_ceName)), 0);
660 m_pCmd->Add(cmdCreate);
661 // create entity
662 cmdCreate = new CINCOObject("Create", 0);
663 cmdCreate->Add(new CINCOProcedure(REG_TYP_CLS_FCT_NAME_OVLD(Create,
664 CINOSContainer<T>, this, uint32, Create,(const char*, const char*))), 0);
665 cmdCreate->Add(new CINCOstring("Name", m_ceName, sizeof(m_ceName)), 0);
666 cmdCreate->Add(new CINCOstring("Type", m_ceType, sizeof(m_ceType)), 1);
667 m_pCmd->Add(cmdCreate);
668 // create entity
669 cmdCreate = new CINCOObject("Create", 0);
670 cmdCreate->Add(new CINCOProcedure(REG_TYP_CLS_FCT_NAME_OVLD(Create,
671 CINOSContainer<T>, this, uint32, Create,(const char*, const char*, const char*))), 0);
672 cmdCreate->Add(new CINCOstring("Name", m_ceName, sizeof(m_ceName)), 0);
673 cmdCreate->Add(new CINCOstring("Type", m_ceType, sizeof(m_ceType)), 1);
674 cmdCreate->Add(new CINCOstring("Param", m_ceParam, sizeof(m_ceParam)), 2);
675 m_pCmd->Add(cmdCreate);
676
677 // destroy entity
678 CINCOObject* cmdDestroy = new CINCOObject("Destroy", 0);
679 m_pCmd->Add(cmdDestroy);
680 cmdDestroy->Add(new CINCOProcedure(REG_TYP_CLS_FCT_NAME_OVLD(Destroy,
681 CINOSContainer<T>, this, uint32, Destroy,(const char*))), 1);
682 cmdDestroy->Add(new CINCOstring("Name", m_ceName, sizeof(m_ceName)), 0);
683
684 // add prop folder
685 m_pProp=new CINCOObject("Prop", 0);
686 m_pRegister->Add(m_pProp);
687 m_pProp->Add(new CINCOstring("Base", m_cBase, sizeof(m_cBase)), 0);
688
689 } // end if
690 else {
691 // yes -> easy
692 m_pEntity = m_pRegister;
693 } // end else
694
695 // return pointer to my inco object
696 return m_pRegister;
697
698 // end CINOSContainer::Register
699}
700
701//------------------------------------------------------------------------------
702// container class registration
703//------------------------------------------------------------------------------
704
720#define INOS_CONTAINER_CLASS(aClass,aType,aBase) \
721 void* Create##aClass(const char* apName, const char* apParam) \
722 { return new aClass(apName, apParam);}; \
723 static CINOSContainerEntityRegister l_##aClass##Create(Create##aClass, aType, aBase);
724#define INOS_CONTAINER_CLASS_CHECK(aClass,aType,aBase) \
725 void* Create##aClass(const char* apName, const char* apParam) \
726 { return new aClass(apName, apParam);}; \
727 static CINOSContainerEntityRegister l_##aClass##Create(Create##aClass, aType, aBase, &aClass::CheckTarget);
728
737#define INOS_CONTAINER_CLASS_MI(aClass,aBaseClass,aType,aBase) \
738 template <typename T> \
739 void* Create##aClass(const char* apName, const char* apParam) \
740 /* cast to T* (not just void*) is important, if T* is not the first base class from which aClass derives. See http://stackoverflow.com/questions/2379427/multiple-inheritance-unexpected-result-after-cast-from-void-to-2nd-base-class */ \
741 { return static_cast<T*>(new aClass(apName, apParam));}; \
742 static CINOSContainerEntityRegister l_##aClass##Create(Create##aClass<aBaseClass>, aType, aBase);
743
744//------------------------------------------------------------------------------
745// end of file
746//------------------------------------------------------------------------------
747
748#endif // INC_CINOSCONTAINER_H
#define DECLARE_DYNAMIC_T(aClass, aT)
Definition cinospartitionmemory.h:330
#define DECLARE_DYNAMIC(aClass)
Definition cinospartitionmemory.h:328
#define IMPLEMENT_DYNAMIC_T(aClass, aT)
Definition cinospartitionmemory.h:363
Definition cinoscontainer.h:258
Definition cinoscontainer.h:220
Definition cinoscontainer.h:104
void * m_pHookMtd
pointer to hook method
Definition cinoscontainer.h:178
CINOSContainer(const char *apName, const char *apElementBases)
Definition cinoscontainer.h:279
virtual uint32 GetNumber()
return number of entities
Definition cinoscontainer.h:459
int16 m_iOrder
inco tree order
Definition cinoscontainer.h:190
void * m_pParent
pointer to container parent
Definition cinoscontainer.h:174
virtual void Remove(T *apEntity, bool abDelete=true)
remove entity from container
Definition cinoscontainer.h:398
uint32 Destroy(const char *apName)
destroy entity
Definition cinoscontainer.h:555
CINCOObject * GetRegister(bool abLight=false)
get pointer to inco registration
Definition cinoscontainer.h:634
uint32 Create(const char *apName)
create entity
Definition cinoscontainer.h:482
uint32 Create(const char *apName, const char *apType)
create entity
Definition cinoscontainer.h:490
char m_ceType[32]
entity type
Definition cinoscontainer.h:195
virtual T * GetAt(uint32 auIndex)
return pointer to entity auIndex
Definition cinoscontainer.h:453
TINOSNameBalancedBinaryTree< T > * m_pEntities
pool of all entities
Definition cinoscontainer.h:180
uint32 Create(const char *apName, const char *apType, const char *apParam)
create entity
Definition cinoscontainer.h:499
virtual void Add(T *apEntity)
add entity to container
Definition cinoscontainer.h:352
CINCOObject * m_pRegister
pointer to inco registration
Definition cinoscontainer.h:182
CINCOObject * m_pCmd
pointer to command folder
Definition cinoscontainer.h:184
CINCOObject * m_pProp
Pointer to prop folder.
Definition cinoscontainer.h:188
char m_cName[32]
container name
Definition cinoscontainer.h:170
void SetParent(void *apParent)
set container parent
Definition cinoscontainer.h:340
void SetBase(const char *apElementBases)
Definition cinoscontainer.h:346
CINCOObject * m_pEntity
pointer to entity folder
Definition cinoscontainer.h:186
void SetName(const char *apName)
Set different name for registration. Only works prior to registration.
Definition cinoscontainer.h:123
virtual ~CINOSContainer()
destructor
Definition cinoscontainer.h:321
char m_cBase[256]
pointer to string of all supported base types
Definition cinoscontainer.h:172
uint32 Check(const char *apType, const char *apParam)
check if it is allowed to create entity of apType
Definition cinoscontainer.h:625
char m_ceName[64]
entity name
Definition cinoscontainer.h:193
void * m_pHookObj
pointer to hook object
Definition cinoscontainer.h:176
virtual T * Find(const char *apName)
return pointer to entity 'apName'
Definition cinoscontainer.h:447
void RegisterHook(void *apObject, void *apMethod)
register event hook
Definition cinoscontainer.h:475
char m_ceParam[256]
entity param's
Definition cinoscontainer.h:197
#define ASSERT_ALWAYS(f)
Definition inosmacro.h:696