Files
wc3re/Resource.hh

130 lines
2.1 KiB
C++

#ifndef WC3RE_RESOURCE_HH__
#define WC3RE_RESOURCE_HH__
#include <cstdint>
#include <cstddef>
#include <string>
#include <memory>
#include <atomic>
#include <cassert>
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<unsigned int> ref_;
};
template<class Resource>
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<Resource>;
};
#endif