#pragma once

#include <carb/flatcache/Allocator.h>


namespace omni
{
namespace gpucompute
{
struct GpuCompute;
struct Context;
} // namespace gpucompute
} // namespace omni


namespace carb
{
namespace flatcache
{
struct Platform
{
    Allocator allocator;

    omni::gpucompute::GpuCompute* gpuCuda = nullptr;
    omni::gpucompute::Context* gpuCudaCtx = nullptr;

    // The gpuD3dVk interface is used only if you access GPU arrays using D3D or Vulkan.
    // If you're only using CPU or CUDA GPU arrays then you don't set it.
    omni::gpucompute::GpuCompute* gpuD3dVk = nullptr;
    omni::gpucompute::Context* gpuD3dVkCtx = nullptr;

    Platform() = default;

    Platform(const Platform& other) = delete;
    Platform& operator=(const Platform& other) = delete;

    Platform(Platform&& other) = default;
    Platform& operator=(Platform&& other) = default;

    inline void reset()
    {
        gpuD3dVk = nullptr;
        gpuD3dVkCtx = nullptr;

        gpuCuda = nullptr;
        gpuCudaCtx = nullptr;

        allocator.~Allocator();
        new (&allocator) Allocator();
    }

    // mirror of IPlatform functions
    static void get(const PlatformId& id);
    static void getMutable(const PlatformId& id);
    static void reset(const PlatformId& id);
    static void resetAll();
};
} // namespace flatcache

} // namespace carb
