2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-04-21 10:58:44 +00:00

chore: dynamically enable shader compilation if available

This commit is contained in:
Jan Laupetin
2026-03-25 22:47:50 +01:00
parent e814f7382c
commit b283695e1c
7 changed files with 381 additions and 230 deletions

View File

@@ -1,20 +1,13 @@
#include "PixelShaderCompilerIW4.h" #include "PixelShaderCompilerIW4.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Shader/ShaderCommon.h" #include "Shader/D3DShaderCompiler.h"
#include "Techset/ShaderIncludeHandler.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#ifdef _WIN32
#include <d3dcompiler.h>
#pragma comment(lib, "d3dcompiler.lib")
#endif
using namespace IW4; using namespace IW4;
namespace namespace
@@ -30,74 +23,28 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{ {
#ifdef _WIN32 auto result = shader::CompileShader(assetName, "PSMain", "ps_3_0", false, m_search_path, m_memory);
const auto fileName = shader::GetSourceFileNameForShaderAssetName(assetName);
auto file = m_search_path.Open(fileName); if (result.has_value())
if (!file.IsOpen() || file.m_length <= 0) {
const std::optional maybeShader(*std::move(result));
if (!maybeShader.has_value())
return AssetCreationResult::NoAction(); return AssetCreationResult::NoAction();
if (std::cmp_greater(file.m_length, techset::ShaderIncludeHandler::MAX_SHADER_SIZE))
{
con::error("Invalid shader source \"{}\": File too big: {}", assetName, file.m_length);
return AssetCreationResult::Failure();
}
const auto shaderSize = static_cast<size_t>(file.m_length);
const auto shaderData = std::make_unique<char[]>(shaderSize);
file.m_stream->read(shaderData.get(), shaderSize);
file.m_stream.reset();
constexpr unsigned shaderFlags = D3DCOMPILE_OPTIMIZATION_LEVEL1
#ifdef _DEBUG
| D3DCOMPILE_DEBUG
#endif
;
techset::ShaderIncludeHandler shaderIncluder(m_search_path);
ID3DBlob* shaderBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
const auto errorCode = D3DCompile(
shaderData.get(), shaderSize, assetName.c_str(), nullptr, &shaderIncluder, "PSMain", "ps_3_0", shaderFlags, 0u, &shaderBlob, &errorBlob);
if (FAILED(errorCode))
{
con::error("Invalid pixel shader \"{}\": Compilation error", assetName);
if (errorBlob)
{
std::cerr << " " << static_cast<char*>(errorBlob->GetBufferPointer()) << "\n";
errorBlob->Release();
}
if (shaderBlob)
shaderBlob->Release();
return AssetCreationResult::Failure();
}
con::info("Compiled pixel shader \"{}\"", assetName); con::info("Compiled pixel shader \"{}\"", assetName);
const auto shaderBlobSize = static_cast<size_t>(shaderBlob->GetBufferSize()); assert(maybeShader->m_shader_size % sizeof(uint32_t) == 0);
assert(shaderBlobSize % sizeof(uint32_t) == 0);
auto* pixelShader = m_memory.Alloc<MaterialPixelShader>(); auto* pixelShader = m_memory.Alloc<MaterialPixelShader>();
pixelShader->name = m_memory.Dup(assetName.c_str()); pixelShader->name = m_memory.Dup(assetName.c_str());
pixelShader->prog.loadDef.programSize = static_cast<uint16_t>(shaderBlobSize / sizeof(uint32_t)); pixelShader->prog.loadDef.program = static_cast<unsigned int*>(maybeShader->m_shader_bin);
pixelShader->prog.loadDef.loadForRenderer = 0; pixelShader->prog.loadDef.programSize = static_cast<uint16_t>(maybeShader->m_shader_size / sizeof(uint32_t));
pixelShader->prog.ps = nullptr;
auto* assetShaderBuffer = m_memory.Alloc<char>(shaderBlobSize);
memcpy(assetShaderBuffer, shaderBlob->GetBufferPointer(), shaderBlobSize);
pixelShader->prog.loadDef.program = reinterpret_cast<uint32_t*>(assetShaderBuffer);
shaderBlob->Release();
return AssetCreationResult::Success(context.AddAsset(AssetRegistration<AssetPixelShader>(assetName, pixelShader))); return AssetCreationResult::Success(context.AddAsset(AssetRegistration<AssetPixelShader>(assetName, pixelShader)));
#else }
// Shader compilation is only support with Windows
return AssetCreationResult::NoAction(); con::error("Failed to compile pixel shader \"{}\": {}", assetName, result.error());
#endif return AssetCreationResult::Failure();
} }
void FinalizeZone(AssetCreationContext& context) override {} void FinalizeZone(AssetCreationContext& context) override {}
@@ -112,6 +59,9 @@ namespace techset
{ {
std::unique_ptr<IAssetCreator> CreatePixelShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath) std::unique_ptr<IAssetCreator> CreatePixelShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath)
{ {
if (!shader::ShaderCompilationAvailable())
return nullptr;
return std::make_unique<PixelShaderCompilerIW4>(memory, searchPath); return std::make_unique<PixelShaderCompilerIW4>(memory, searchPath);
} }
} // namespace techset } // namespace techset

View File

@@ -1,20 +1,13 @@
#include "VertexShaderCompilerIW4.h" #include "VertexShaderCompilerIW4.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Shader/ShaderCommon.h" #include "Shader/D3DShaderCompiler.h"
#include "Techset/ShaderIncludeHandler.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#ifdef _WIN32
#include <d3dcompiler.h>
#pragma comment(lib, "d3dcompiler.lib")
#endif
using namespace IW4; using namespace IW4;
namespace namespace
@@ -30,74 +23,28 @@ namespace
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{ {
#ifdef _WIN32 auto result = shader::CompileShader(assetName, "VSMain", "vs_3_0", false, m_search_path, m_memory);
const auto fileName = shader::GetSourceFileNameForShaderAssetName(assetName);
auto file = m_search_path.Open(fileName); if (result.has_value())
if (!file.IsOpen() || file.m_length <= 0) {
const std::optional maybeShader(*std::move(result));
if (!maybeShader.has_value())
return AssetCreationResult::NoAction(); return AssetCreationResult::NoAction();
if (std::cmp_greater(file.m_length, techset::ShaderIncludeHandler::MAX_SHADER_SIZE))
{
con::error("Invalid shader source \"{}\": File too big: {}", assetName, file.m_length);
return AssetCreationResult::Failure();
}
const auto shaderSize = static_cast<size_t>(file.m_length);
const auto shaderData = std::make_unique<char[]>(shaderSize);
file.m_stream->read(shaderData.get(), shaderSize);
file.m_stream.reset();
constexpr unsigned shaderFlags = D3DCOMPILE_OPTIMIZATION_LEVEL1
#ifdef _DEBUG
| D3DCOMPILE_DEBUG
#endif
;
techset::ShaderIncludeHandler shaderIncluder(m_search_path);
ID3DBlob* shaderBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
const auto errorCode = D3DCompile(
shaderData.get(), shaderSize, assetName.c_str(), nullptr, &shaderIncluder, "VSMain", "vs_3_0", shaderFlags, 0u, &shaderBlob, &errorBlob);
if (FAILED(errorCode))
{
con::error("Invalid vertex shader \"{}\": Compilation error", assetName);
if (errorBlob)
{
std::cerr << " " << static_cast<char*>(errorBlob->GetBufferPointer()) << "\n";
errorBlob->Release();
}
if (shaderBlob)
shaderBlob->Release();
return AssetCreationResult::Failure();
}
con::info("Compiled vertex shader \"{}\"", assetName); con::info("Compiled vertex shader \"{}\"", assetName);
const auto shaderBlobSize = static_cast<size_t>(shaderBlob->GetBufferSize()); assert(maybeShader->m_shader_size % sizeof(uint32_t) == 0);
assert(shaderBlobSize % sizeof(uint32_t) == 0);
auto* vertexShader = m_memory.Alloc<MaterialVertexShader>(); auto* vertexShader = m_memory.Alloc<MaterialVertexShader>();
vertexShader->name = m_memory.Dup(assetName.c_str()); vertexShader->name = m_memory.Dup(assetName.c_str());
vertexShader->prog.loadDef.programSize = static_cast<uint16_t>(shaderBlobSize / sizeof(uint32_t)); vertexShader->prog.loadDef.program = static_cast<unsigned int*>(maybeShader->m_shader_bin);
vertexShader->prog.loadDef.loadForRenderer = 0; vertexShader->prog.loadDef.programSize = static_cast<uint16_t>(maybeShader->m_shader_size / sizeof(uint32_t));
vertexShader->prog.vs = nullptr;
auto* assetShaderBuffer = m_memory.Alloc<char>(shaderBlobSize);
memcpy(assetShaderBuffer, shaderBlob->GetBufferPointer(), shaderBlobSize);
vertexShader->prog.loadDef.program = reinterpret_cast<uint32_t*>(assetShaderBuffer);
shaderBlob->Release();
return AssetCreationResult::Success(context.AddAsset(AssetRegistration<AssetVertexShader>(assetName, vertexShader))); return AssetCreationResult::Success(context.AddAsset(AssetRegistration<AssetVertexShader>(assetName, vertexShader)));
#else }
// Shader compilation is only support with Windows
return AssetCreationResult::NoAction(); con::error("Failed to compile vertex shader \"{}\": {}", assetName, result.error());
#endif return AssetCreationResult::Failure();
} }
void FinalizeZone(AssetCreationContext& context) override {} void FinalizeZone(AssetCreationContext& context) override {}
@@ -112,6 +59,9 @@ namespace techset
{ {
std::unique_ptr<IAssetCreator> CreateVertexShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath) std::unique_ptr<IAssetCreator> CreateVertexShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath)
{ {
if (!shader::ShaderCompilationAvailable())
return nullptr;
return std::make_unique<VertexShaderCompilerIW4>(memory, searchPath); return std::make_unique<VertexShaderCompilerIW4>(memory, searchPath);
} }
} // namespace techset } // namespace techset

View File

@@ -0,0 +1,302 @@
#include "D3DShaderCompiler.h"
#include "Shader/ShaderCommon.h"
#include "Utils/Logging/Log.h"
#include <cassert>
#include <cstdint>
#include <iostream>
#include <memory>
#include <utility>
#ifdef _WIN32
#include <Windows.h>
#endif
namespace
{
// The types based on vkd3d which is licensed under the
// GNU Lesser General Public License as published by the Free Software Foundation
// All types are prefixed with OAT_ to not cause conflicts as the original definition may be included
// depending on the platform.
// Types were duplicated to be available on any platform and to not require the corresponding library
// to be installed
typedef int OAT_HRESULT;
#define OAT_SUCCEEDED(hr) ((OAT_HRESULT)(hr) >= 0)
#define OAT_FAILED(hr) ((OAT_HRESULT)(hr) < 0)
typedef unsigned int OAT_ULONG;
typedef unsigned long OAT_ULONG_PTR;
typedef OAT_ULONG_PTR OAT_SIZE_T;
#define OAT_HRESULT_TYPEDEF(x) ((OAT_HRESULT)x)
#define OAT_S_OK OAT_HRESULT_TYPEDEF(0)
#define OAT_S_FALSE OAT_HRESULT_TYPEDEF(1)
#define OAT_E_FAIL OAT_HRESULT_TYPEDEF(0x80004005)
#define OAT_D3DCOMPILE_DEBUG 0x00000001
#define OAT_D3DCOMPILE_SKIP_VALIDATION 0x00000002
#define OAT_D3DCOMPILE_SKIP_OPTIMIZATION 0x00000004
#define OAT_D3DCOMPILE_PACK_MATRIX_ROW_MAJOR 0x00000008
#define OAT_D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR 0x00000010
#define OAT_D3DCOMPILE_PARTIAL_PRECISION 0x00000020
#define OAT_D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT 0x00000040
#define OAT_D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT 0x00000080
#define OAT_D3DCOMPILE_NO_PRESHADER 0x00000100
#define OAT_D3DCOMPILE_AVOID_FLOW_CONTROL 0x00000200
#define OAT_D3DCOMPILE_PREFER_FLOW_CONTROL 0x00000400
#define OAT_D3DCOMPILE_ENABLE_STRICTNESS 0x00000800
#define OAT_D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY 0x00001000
#define OAT_D3DCOMPILE_IEEE_STRICTNESS 0x00002000
#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL0 0x00004000
#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL1 0x00000000
#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL2 0x0000c000
#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL3 0x00008000
#define OAT_D3DCOMPILE_RESERVED16 0x00010000
#define OAT_D3DCOMPILE_RESERVED17 0x00020000
#define OAT_D3DCOMPILE_WARNINGS_ARE_ERRORS 0x00040000
#define OAT_D3DCOMPILE_RESOURCES_MAY_ALIAS 0x00080000
#define OAT_D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES 0x00100000
#define OAT_D3DCOMPILE_ALL_RESOURCES_BOUND 0x00200000
#define OAT_D3DCOMPILE_DEBUG_NAME_FOR_SOURCE 0x00400000
#define OAT_D3DCOMPILE_DEBUG_NAME_FOR_BINARY 0x00800000
enum OAT_D3D_INCLUDE_TYPE : uint32_t
{
OAT_D3D_INCLUDE_LOCAL = 0,
OAT_D3D_INCLUDE_SYSTEM = 1
};
struct OAT_ID3DInclude
{
virtual OAT_HRESULT __stdcall Open(
OAT_D3D_INCLUDE_TYPE includeType, const char* fileName, const void* parentData, const void** data, unsigned int* size) = 0;
virtual OAT_HRESULT __stdcall Close(const void* data) = 0;
};
struct OAT_GUID
{
unsigned int Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
};
typedef OAT_GUID OAT_IID;
struct OAT_IUnknown
{
virtual OAT_HRESULT __stdcall QueryInterface(const OAT_IID& riid, void** object) = 0;
virtual OAT_ULONG __stdcall AddRef() = 0;
virtual OAT_ULONG __stdcall Release() = 0;
};
struct OAT_ID3DBlob : OAT_IUnknown
{
virtual void* __stdcall GetBufferPointer() = 0;
virtual OAT_SIZE_T __stdcall GetBufferSize() = 0;
};
struct OAT_D3D_SHADER_MACRO
{
const char* Name;
const char* Definition;
};
typedef OAT_HRESULT(__stdcall* D3DCompile_t)(const void* data,
OAT_SIZE_T dataSize,
const char* filename,
const OAT_D3D_SHADER_MACRO* defines,
OAT_ID3DInclude* include,
const char* entrypoint,
const char* target,
unsigned int flags,
unsigned int effectFlags,
OAT_ID3DBlob** shader,
OAT_ID3DBlob** errorMessages);
constexpr size_t MAX_SHADER_SIZE = 0x1900000u;
class ShaderIncludeHandler : public OAT_ID3DInclude
{
public:
explicit ShaderIncludeHandler(ISearchPath& searchPath)
: m_search_path(searchPath)
{
}
OAT_HRESULT
__stdcall Open(OAT_D3D_INCLUDE_TYPE includeType, const char* fileName, const void* parentData, const void** data, unsigned int* size) override
{
const auto fullFileName = shader::GetSourceFileNameForShaderAssetName(fileName);
auto file = m_search_path.Open(fullFileName);
if (!file.IsOpen() || file.m_length <= 0)
return OAT_E_FAIL;
if (std::cmp_greater(file.m_length, MAX_SHADER_SIZE))
{
con::error("Invalid shader source \"{}\": File too big: {}\n", fileName, file.m_length);
return OAT_E_FAIL;
}
const auto shaderSize = static_cast<size_t>(file.m_length);
auto shaderData = std::make_unique<char[]>(shaderSize);
file.m_stream->read(shaderData.get(), static_cast<std::streamsize>(shaderSize));
file.m_stream.reset();
*data = shaderData.get();
*size = static_cast<unsigned int>(shaderSize);
m_file_buffers_in_use.push_back(std::move(shaderData));
return OAT_S_OK;
}
OAT_HRESULT __stdcall Close(const void* data) override
{
for (auto i = m_file_buffers_in_use.begin(); i != m_file_buffers_in_use.end(); ++i)
{
if (i->get() == data)
{
m_file_buffers_in_use.erase(i);
return OAT_S_OK;
}
}
return OAT_E_FAIL;
}
private:
ISearchPath& m_search_path;
std::vector<std::unique_ptr<char[]>> m_file_buffers_in_use;
};
bool initialized = false;
bool compilationAvailable = false;
D3DCompile_t d3dCompile = nullptr;
void PrintInitializationFailedMessage()
{
#ifdef _WIN32
con::warn("Could not initialize shader compilation. Make sure DirectX is installed on your machine if you want to make use of it.");
#endif
}
void InitializeShaderCompilation()
{
initialized = true;
#ifdef _WIN32
const auto d3dCompiler = LoadLibraryA("D3DCOMPILER_47.dll");
if (!d3dCompiler)
{
PrintInitializationFailedMessage();
return;
}
const auto d3dCompileAddress = GetProcAddress(d3dCompiler, "D3DCompile");
if (!d3dCompileAddress)
{
PrintInitializationFailedMessage();
return;
}
d3dCompile = reinterpret_cast<D3DCompile_t>(d3dCompileAddress);
compilationAvailable = true;
#endif
}
} // namespace
namespace shader
{
bool ShaderCompilationAvailable()
{
if (!initialized)
InitializeShaderCompilation();
return compilationAvailable;
}
result::Expected<std::optional<CompiledShader>, std::string> CompileShader(const std::string& shaderFile,
const std::string& entryPoint,
const std::string& target,
const bool debug,
ISearchPath& searchPath,
MemoryManager& memory)
{
if (!initialized)
InitializeShaderCompilation();
if (!compilationAvailable)
return result::Unexpected<std::string>("Shader compilation unavailable");
const auto fileName = GetSourceFileNameForShaderAssetName(shaderFile);
auto file = searchPath.Open(fileName);
if (!file.IsOpen() || file.m_length <= 0)
return std::optional<CompiledShader>(std::nullopt);
if (std::cmp_greater(file.m_length, MAX_SHADER_SIZE))
return result::Unexpected(std::format("File too big: {}", file.m_length));
const auto shaderSize = file.m_length;
const auto shaderData = std::make_unique<char[]>(static_cast<size_t>(shaderSize));
file.m_stream->read(shaderData.get(), static_cast<std::streamsize>(shaderSize));
file.m_stream.reset();
unsigned shaderFlags = OAT_D3DCOMPILE_OPTIMIZATION_LEVEL1;
if (debug)
shaderFlags |= OAT_D3DCOMPILE_DEBUG;
ShaderIncludeHandler shaderIncluder(searchPath);
OAT_ID3DBlob* shaderBlob = nullptr;
OAT_ID3DBlob* errorBlob = nullptr;
const auto errorCode = d3dCompile(shaderData.get(),
static_cast<OAT_SIZE_T>(shaderSize),
fileName.c_str(),
nullptr,
&shaderIncluder,
entryPoint.c_str(),
target.c_str(),
shaderFlags,
0u,
&shaderBlob,
&errorBlob);
if (OAT_FAILED(errorCode))
{
std::string errorMessage;
if (errorBlob)
{
errorMessage = std::format("Compilation error: {}", static_cast<const char*>(errorBlob->GetBufferPointer()));
errorBlob->Release();
}
else
{
errorMessage = "Unknown compilation error";
}
if (shaderBlob)
shaderBlob->Release();
return result::Unexpected(std::move(errorMessage));
}
const auto shaderBlobSize = static_cast<size_t>(shaderBlob->GetBufferSize());
auto* assetShaderBuffer = memory.Alloc<char>(shaderBlobSize);
memcpy(assetShaderBuffer, shaderBlob->GetBufferPointer(), shaderBlobSize);
shaderBlob->Release();
return std::optional(CompiledShader{
.m_shader_bin = assetShaderBuffer,
.m_shader_size = shaderBlobSize,
});
}
} // namespace shader

View File

@@ -0,0 +1,23 @@
#pragma once
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include "Utils/Result.h"
#include <optional>
#include <string>
namespace shader
{
class CompiledShader
{
public:
void* m_shader_bin;
size_t m_shader_size;
};
bool ShaderCompilationAvailable();
result::Expected<std::optional<CompiledShader>, std::string> CompileShader(
const std::string& shaderFile, const std::string& entryPoint, const std::string& target, bool debug, ISearchPath& searchPath, MemoryManager& memory);
} // namespace shader

View File

@@ -1,59 +0,0 @@
#include "ShaderIncludeHandler.h"
#include "Shader/ShaderCommon.h"
#include "Utils/Logging/Log.h"
#include <iostream>
#include <utility>
#ifdef _WIN32
namespace techset
{
ShaderIncludeHandler::ShaderIncludeHandler(ISearchPath& searchPath)
: m_search_path(searchPath)
{
}
HRESULT ShaderIncludeHandler::Open(D3D_INCLUDE_TYPE includeType, const LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes)
{
const auto fileName = shader::GetSourceFileNameForShaderAssetName(pFileName);
auto file = m_search_path.Open(fileName);
if (!file.IsOpen() || file.m_length <= 0)
return E_FAIL;
if (std::cmp_greater(file.m_length, MAX_SHADER_SIZE))
{
con::error("Invalid shader source \"{}\": File too big: {}\n", pFileName, file.m_length);
return E_FAIL;
}
const auto shaderSize = static_cast<size_t>(file.m_length);
auto shaderData = std::make_unique<char[]>(shaderSize);
file.m_stream->read(shaderData.get(), static_cast<std::streamsize>(shaderSize));
file.m_stream.reset();
*ppData = shaderData.get();
*pBytes = static_cast<UINT>(shaderSize);
m_file_buffers_in_use.push_back(std::move(shaderData));
return S_OK;
}
HRESULT ShaderIncludeHandler::Close(const LPCVOID pData)
{
for (auto i = m_file_buffers_in_use.begin(); i != m_file_buffers_in_use.end(); ++i)
{
if (i->get() == pData)
{
m_file_buffers_in_use.erase(i);
return S_OK;
}
}
return E_FAIL;
}
} // namespace techset
#endif

View File

@@ -1,27 +0,0 @@
#pragma once
#include "SearchPath/ISearchPath.h"
// Shader compilation only available on Windows
#ifdef _WIN32
#include <d3dcompiler.h>
namespace techset
{
class ShaderIncludeHandler : public ID3DInclude
{
public:
static constexpr size_t MAX_SHADER_SIZE = 0x1900000u;
explicit ShaderIncludeHandler(ISearchPath& searchPath);
virtual ~ShaderIncludeHandler() = default;
HRESULT __declspec(nothrow) __stdcall Open(D3D_INCLUDE_TYPE includeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) override;
HRESULT __declspec(nothrow) __stdcall Close(LPCVOID pData) override;
private:
ISearchPath& m_search_path;
std::vector<std::unique_ptr<char[]>> m_file_buffers_in_use;
};
} // namespace techset
#endif

View File

@@ -13,6 +13,9 @@ AssetCreatorCollection::AssetCreatorCollection(const Zone& zone)
void AssetCreatorCollection::AddAssetCreator(std::unique_ptr<IAssetCreator> creator) void AssetCreatorCollection::AddAssetCreator(std::unique_ptr<IAssetCreator> creator)
{ {
if (!creator)
return;
const auto maybeHandlingAssetType = creator->GetHandlingAssetType(); const auto maybeHandlingAssetType = creator->GetHandlingAssetType();
assert(!maybeHandlingAssetType || static_cast<unsigned>(*maybeHandlingAssetType) < m_asset_creators_by_type.size()); assert(!maybeHandlingAssetType || static_cast<unsigned>(*maybeHandlingAssetType) < m_asset_creators_by_type.size());
if (maybeHandlingAssetType && static_cast<unsigned>(*maybeHandlingAssetType) < m_asset_creators_by_type.size()) if (maybeHandlingAssetType && static_cast<unsigned>(*maybeHandlingAssetType) < m_asset_creators_by_type.size())
@@ -23,6 +26,9 @@ void AssetCreatorCollection::AddAssetCreator(std::unique_ptr<IAssetCreator> crea
void AssetCreatorCollection::AddSubAssetCreator(std::unique_ptr<ISubAssetCreator> creator) void AssetCreatorCollection::AddSubAssetCreator(std::unique_ptr<ISubAssetCreator> creator)
{ {
if (!creator)
return;
const auto maybeHandlingSubAssetType = creator->GetHandlingSubAssetType(); const auto maybeHandlingSubAssetType = creator->GetHandlingSubAssetType();
assert(!maybeHandlingSubAssetType || static_cast<unsigned>(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size()); assert(!maybeHandlingSubAssetType || static_cast<unsigned>(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size());
if (maybeHandlingSubAssetType && static_cast<unsigned>(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size()) if (maybeHandlingSubAssetType && static_cast<unsigned>(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size())
@@ -33,6 +39,9 @@ void AssetCreatorCollection::AddSubAssetCreator(std::unique_ptr<ISubAssetCreator
void AssetCreatorCollection::AddAssetPostProcessor(std::unique_ptr<IAssetPostProcessor> postProcessor) void AssetCreatorCollection::AddAssetPostProcessor(std::unique_ptr<IAssetPostProcessor> postProcessor)
{ {
if (!postProcessor)
return;
const auto handlingAssetType = postProcessor->GetHandlingAssetType(); const auto handlingAssetType = postProcessor->GetHandlingAssetType();
assert(static_cast<unsigned>(handlingAssetType) < m_asset_post_processors_by_type.size()); assert(static_cast<unsigned>(handlingAssetType) < m_asset_post_processors_by_type.size());
if (static_cast<unsigned>(handlingAssetType) < m_asset_post_processors_by_type.size()) if (static_cast<unsigned>(handlingAssetType) < m_asset_post_processors_by_type.size())
@@ -43,6 +52,9 @@ void AssetCreatorCollection::AddAssetPostProcessor(std::unique_ptr<IAssetPostPro
void AssetCreatorCollection::AddDefaultAssetCreator(std::unique_ptr<IDefaultAssetCreator> defaultAssetCreator) void AssetCreatorCollection::AddDefaultAssetCreator(std::unique_ptr<IDefaultAssetCreator> defaultAssetCreator)
{ {
if (!defaultAssetCreator)
return;
const auto handlingAssetType = defaultAssetCreator->GetHandlingAssetType(); const auto handlingAssetType = defaultAssetCreator->GetHandlingAssetType();
assert(static_cast<unsigned>(handlingAssetType) < m_default_asset_creators_by_type.size()); assert(static_cast<unsigned>(handlingAssetType) < m_default_asset_creators_by_type.size());
assert(!m_default_asset_creators_by_type[handlingAssetType]); assert(!m_default_asset_creators_by_type[handlingAssetType]);