#pragma once #include "resource.h" #include "chain.h" #include "node.h" #include "plug.h" #include "graph2d.h" //####################################################################### // WarehouseObject //####################################################################### class WarehouseObject : public Plug { friend class WarehouseBin; public: WarehouseObject( const char *new_name, Logical keep_forever = False ); WarehouseObject( ResourceDescription::ResourceID new_resource_id, Logical keep_forever = False ); ~WarehouseObject(); Logical TestInstance() const; void SetKeepForever(Logical keep_forever) { Check(this); keepForever = keep_forever; } Logical GetKeepForever() { Check(this); return keepForever; } void Reference() { Check(this); ++referenceCount; } Logical Unreference() // returns True if no longer referenced { Check(this); return (Logical) ((--referenceCount) <= 0); } protected: char name[32]; ResourceDescription::ResourceID resourceID; int referenceCount; Logical keepForever; }; //----------------------------------------------------------------------- // WarehouseObjectOf //----------------------------------------------------------------------- template class WarehouseObjectOf: public WarehouseObject { public: WarehouseObjectOf( const char *new_name, T *new_pointer, Logical keep_forever = False ); WarehouseObjectOf( ResourceDescription::ResourceID new_resource_id, T *new_pointer, Logical keep_forever = False ); virtual ~WarehouseObjectOf(); Logical TestInstance() const; T *dataPointer; }; template WarehouseObjectOf::WarehouseObjectOf( const char *new_name, T *new_pointer, Logical keep_forever ): WarehouseObject(new_name, keep_forever) { Register_Pointer(new_pointer); dataPointer = new_pointer; } template WarehouseObjectOf::WarehouseObjectOf( ResourceDescription::ResourceID new_resource_id, T *new_pointer, Logical keep_forever ): WarehouseObject(new_resource_id, keep_forever) { Register_Pointer(new_pointer); dataPointer = new_pointer; } template WarehouseObjectOf::~WarehouseObjectOf() { Check(dataPointer); Unregister_Pointer(dataPointer); delete dataPointer; dataPointer = NULL; // safety check } template Logical WarehouseObjectOf::TestInstance() const { Check_Pointer(this); Check_Pointer(dataPointer); return WarehouseObject::TestInstance(); } //####################################################################### // WarehouseBin //####################################################################### class WarehouseBin : public Node { public: WarehouseBin(); ~WarehouseBin(); Logical TestInstance() const; void Add(WarehouseObject *new_object) { Check(this); Check_Pointer(new_object); instanceList.Add(new_object); } void Remove(void *old_object); WarehouseObject * Find(const char *name); WarehouseObject * Find(ResourceDescription::ResourceID new_resource_id); protected: ChainOf instanceList; }; template class WarehouseBinOf : public WarehouseBin { friend class WarehouseBin; public: WarehouseBinOf(); ~WarehouseBinOf(); Logical TestInstance() const; T* Get( const char *name, Logical keep_forever = False ); T* Get( ResourceDescription::ResourceID new_resource_id, Logical keep_forever = False ); T* GetIfAlreadyExists( const char *name ); T* GetIfAlreadyExists( ResourceDescription::ResourceID new_resource_id ); void Release( const char *name ); void Release( ResourceDescription::ResourceID new_resource_id ); void Purge(); }; //-------------------------------------------------------------------- template Logical WarehouseBinOf::TestInstance() const { Check_Pointer(this); return WarehouseBin::TestInstance(); } //-------------------------------------------------------------------- template WarehouseBinOf::WarehouseBinOf() : WarehouseBin() { } //-------------------------------------------------------------------- template WarehouseBinOf::~WarehouseBinOf() { Check(this); Purge(); // remove EVERYTHING unconditionally Check_Fpu(); } //-------------------------------------------------------------------- template T* WarehouseBinOf::Get( const char *name, Logical keep_forever ) { Check(this); WarehouseObjectOf *instance = (WarehouseObjectOf*) WarehouseBin::Find(name); if (instance != NULL) { instance->Reference(); return instance->dataPointer; } else { T *new_object = T::Make(name); if (new_object != NULL) { Check(new_object); // new_object is registered in the warehouseObject creator instance = new WarehouseObjectOf( name, new_object, keep_forever ); Register_Object(instance); WarehouseBin::Add(instance); return new_object; } } return NULL; } template T* WarehouseBinOf::Get( ResourceDescription::ResourceID new_resource_id, Logical keep_forever ) { Check(this); WarehouseObjectOf *instance = (WarehouseObjectOf*) WarehouseBin::Find(new_resource_id); if (instance != NULL) { instance->Reference(); return instance->dataPointer; } else { T *new_object = T::Make(new_resource_id); if (new_object != NULL) { Check(new_object); // new_object is registered in the warehouseObject creator instance = new WarehouseObjectOf( new_resource_id, new_object, keep_forever ); Register_Object(instance); WarehouseBin::Add(instance); return new_object; } } return NULL; } //-------------------------------------------------------------------- template T* WarehouseBinOf::GetIfAlreadyExists( const char *name ) { Check(this); Check_Pointer(name); WarehouseObjectOf *warehouse_object = (WarehouseObjectOf *) WarehouseBin::Find(name); if (warehouse_object != NULL) { Check(warehouse_object); warehouse_object->Reference(); Check(warehouse_object->dataPointer); return warehouse_object->dataPointer; } return NULL; } template T* WarehouseBinOf::GetIfAlreadyExists( ResourceDescription::ResourceID id ) { Check(this); WarehouseObjectOf *warehouse_object = (WarehouseObjectOf*) WarehouseBin::Find(id); if (warehouse_object != NULL) { Check(warehouse_object); warehouse_object->Reference(); Check(warehouse_object->dataPointer); return warehouse_object->dataPointer; } return NULL; } //-------------------------------------------------------------------- template void WarehouseBinOf::Release( const char *name ) { Check(this); Check_Pointer(name); WarehouseObjectOf *warehouse_object = (WarehouseObjectOf *) WarehouseBin::Find(name); if (warehouse_object != NULL) { Check(warehouse_object); if (warehouse_object->Unreference()) { if (warehouse_object->GetKeepForever() == False) { Unregister_Object(warehouse_object); // the dataPointer is deregistered & deleted in the destructor delete warehouse_object; } } } } template void WarehouseBinOf::Release( ResourceDescription::ResourceID id ) { Check(this); WarehouseObjectOf *warehouse_object = (WarehouseObjectOf *) WarehouseBin::Find(id); if (warehouse_object != NULL) { Check(warehouse_object); if (warehouse_object->Unreference()) { if (warehouse_object->GetKeepForever() == False) { Unregister_Object(warehouse_object); // the dataPointer is deregistered & deleted in the destructor delete warehouse_object; } } } } template void WarehouseBinOf::Purge() { Check(this); //------------------------------------------ // Delete everything in the bin //------------------------------------------ ChainIteratorOf i(instanceList); WarehouseObject *object_instance; while ((object_instance=i.ReadAndNext()) != NULL) { Check(object_instance); Unregister_Object(object_instance); delete object_instance; } Check_Fpu(); } //####################################################################### // Warehouse //####################################################################### class Warehouse SIGNATURED { public: Warehouse(); virtual ~Warehouse(); Logical TestInstance() const; virtual void Purge(); WarehouseBinOf bitMapBin; WarehouseBinOf pixelMap8Bin; WarehouseBinOf palette8Bin; };