#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_
#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_
#include "native_client/src/include/nacl_base.h"
#include "native_client/src/include/ref_counted.h"
#include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h"
#include "ppapi/c/pp_resource.h"
namespace ppapi_proxy {
#define FOR_ALL_RESOURCES(F) \
F(PluginAudio) \
F(PluginAudioConfig) \
F(PluginBuffer) \
F(PluginFont) \
F(PluginGraphics2D) \
F(PluginGraphics3D) \
F(PluginImageData) \
F(PluginInputEvent) \
F(PluginNetworkMonitorPrivate) \
F(PluginView)
#define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE;
FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS)
#undef DECLARE_RESOURCE_CLASS
class PluginResource : public nacl::RefCountedThreadSafe<PluginResource> {
public:
PluginResource();
template<typename T>
static scoped_refptr<T> GetAs(PP_Resource res) {
scoped_refptr<PluginResource> resource =
PluginResourceTracker::Get()->GetExistingResource(res);
return resource ? resource->Cast<T>() : NULL;
}
template<typename T>
static scoped_refptr<T> AdoptAs(PP_Resource res);
template<typename T>
static scoped_refptr<T> AdoptAsWithNoBrowserCount(PP_Resource res);
template <typename T> T* Cast() { return NULL; }
protected:
virtual ~PluginResource();
virtual bool InitFromBrowserResource(PP_Resource resource) = 0;
private:
friend class nacl::RefCountedThreadSafe<PluginResource>;
#define DEFINE_TYPE_GETTER(RESOURCE) \
virtual RESOURCE* As##RESOURCE() { return NULL; }
FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER)
#undef DEFINE_TYPE_GETTER
#define IMPLEMENT_RESOURCE(RESOURCE) \
virtual RESOURCE* As##RESOURCE() { return this; }
DISALLOW_COPY_AND_ASSIGN(PluginResource);
};
#define DEFINE_RESOURCE_CAST(Type) \
template <> inline Type* PluginResource::Cast<Type>() { \
return As##Type(); \
}
FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST)
#undef DEFINE_RESOURCE_CAST
#undef FOR_ALL_RESOURCES
template<typename T> scoped_refptr<T>
PluginResourceTracker::AdoptBrowserResource(PP_Resource res,
size_t browser_refcount) {
ResourceMap::iterator result = live_resources_.find(res);
if (result == live_resources_.end()) {
scoped_refptr<T> new_resource = new T();
if (new_resource->InitFromBrowserResource(res)) {
AddResource(new_resource, res, browser_refcount);
return new_resource;
} else {
return scoped_refptr<T>();
}
} else {
result->second.browser_refcount += browser_refcount;
return result->second.resource->Cast<T>();
}
}
template<typename T>
scoped_refptr<T> PluginResource::AdoptAs(PP_Resource res) {
if (!res)
return NULL;
const size_t browser_refcount = 1;
return PluginResourceTracker::Get()->AdoptBrowserResource<T>(
res, browser_refcount);
}
template<typename T>
scoped_refptr<T> PluginResource::AdoptAsWithNoBrowserCount(PP_Resource res) {
if (!res)
return NULL;
const size_t browser_refcount = 0;
return PluginResourceTracker::Get()->AdoptBrowserResource<T>(
res, browser_refcount);
}
}
#endif