130 lines
2.1 KiB
C++
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
|