#ifndef WC3RE_RESOURCE_HH__ #define WC3RE_RESOURCE_HH__ #include #include #include #include #include #include class RefCounted { public: RefCounted() : ref_(0) { } virtual ~RefCounted() { assert(ref_ == 0); } virtual void incRef() { ++ref_; } virtual void decRef() { auto old = ref_.fetch_sub(1); assert(old > 0); } virtual unsigned getRef() const { return ref_; } protected: std::atomic ref_; }; template class ResourceHandle { public: ResourceHandle() : res_(nullptr) { } ResourceHandle(Resource& res) : res_(&res) { res_->incRef(); } ResourceHandle(ResourceHandle const& copy) : res_(copy.res_) { if (res_) res_->incRef(); } ResourceHandle(ResourceHandle&& move) : res_(move.res_) { move.res_ = nullptr; } ~ResourceHandle() { if(res_) res_->decRef(); } ResourceHandle& operator=(ResourceHandle const& copy) { Resource* oldRes = res_; res_ = copy.res_; if (res_) res_->incRef(); if (oldRes) oldRes->decRef(); return *this; } ResourceHandle& operator=(ResourceHandle&& move) { res_ = move.res_; move.res_ = nullptr; return *this; } operator bool() const { return res_; } Resource& operator*() { return *res_; } Resource const& operator*() const { return *res_; } Resource* operator->() { return res_; } Resource const* operator->() const { return res_; } private: Resource *res_; }; // Interface for any memory-resident resource // For example mmap'd data file, TRE object, IFF Object, ... class Resource : public RefCounted { public: virtual ~Resource() { } virtual uint8_t const* data() const = 0; virtual size_t size() const = 0; virtual operator bool() const = 0; // The memory footprint of this resource, that is, how much memory would be // freed if this resource is discarded. Used for cache management. virtual size_t footprint() const { return size(); } using Handle = ResourceHandle; }; #endif