Files
parallel-gx1/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp
LibretroAdmin cceb773dbf Replace picojson with libretro-common's rjson
Every JSON reader (Triforce card decks, dynamic input textures, graphics
mods and their per-game profiles) now pulls its file through rjson from a
VFS filestream and fills its structures as it parses, with no document
tree in between. JsonUtil and the vendored picojson go away, as does the
graphics mod serialization nothing called.

Move and scale actions take their X, Y and Z straight from the parsed
feature instead of re-reading a kept JSON value. rjson.c and rjson.h are
imported unchanged from libretro-common.
2026-11-10 06:25:29 +01:00

171 lines
4.7 KiB
C++

// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
#include <vector>
#include <fmt/std.h>
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
#include "Core/System.h"
#include "VideoCommon/Assets/TextureAsset.h"
#include "VideoCommon/Assets/TextureAssetUtils.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/Resources/CustomResourceManager.h"
namespace VideoCommon
{
namespace
{
std::size_t GetAssetSize(const CustomTextureData& data)
{
std::size_t total = 0;
for (const auto& slice : data.m_slices)
{
for (const auto& level : slice.m_levels)
{
total += level.data.size();
}
}
return total;
}
// The maps' values: each begins with the node the map frees it through.
struct AssetMapValue
{
quiesce_node_t node;
Assets::AssetMap map;
};
struct AssetIDValue
{
quiesce_node_t node;
CustomAssetLibrary::AssetID asset_id;
};
void FreeAssetMapValue(quiesce_node_t* node)
{
delete reinterpret_cast<AssetMapValue*>(node);
}
void FreeAssetIDValue(quiesce_node_t* node)
{
delete reinterpret_cast<AssetIDValue*>(node);
}
} // namespace
DirectFilesystemAssetLibrary::DirectFilesystemAssetLibrary()
: m_asset_id_to_asset_map_path(atomic_value_map_new(4096, FreeAssetMapValue)),
m_path_to_asset_id(atomic_value_map_new(4096, FreeAssetIDValue))
{
}
DirectFilesystemAssetLibrary::~DirectFilesystemAssetLibrary()
{
atomic_value_map_free(m_path_to_asset_id);
atomic_value_map_free(m_asset_id_to_asset_map_path);
}
CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const AssetID& asset_id,
CustomTextureData* data)
{
const auto asset_map = GetAssetMapForID(asset_id);
if (asset_map.empty())
{
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - raw texture expected to have one or two files mapped!",
asset_id);
return {};
}
const auto texture_path = asset_map.find("texture");
if (texture_path == asset_map.end())
{
ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have a texture entry mapped!", asset_id);
return {};
}
if (!LoadTextureDataFromFile(asset_id, texture_path->second, AbstractTextureType::Texture_2D,
data))
{
return {};
}
if (!PurgeInvalidMipsFromTextureData(asset_id, data))
return {};
return LoadInfo{GetAssetSize(*data)};
}
void DirectFilesystemAssetLibrary::SetAssetIDMapData(const AssetID& asset_id,
VideoCommon::Assets::AssetMap asset_path_map)
{
AssetMapValue* value;
atomic_value_map_enter(m_asset_id_to_asset_map_path);
value = reinterpret_cast<AssetMapValue*>(
atomic_value_map_get(m_asset_id_to_asset_map_path, asset_id.data(), asset_id.size()));
if (value)
{
for (const auto& [name, path] : value->map)
{
const std::string key = PathToString(path);
atomic_value_map_set(m_path_to_asset_id, key.data(), key.size(), nullptr);
}
}
atomic_value_map_exit(m_asset_id_to_asset_map_path);
for (const auto& [name, path] : asset_path_map)
{
const std::string key = PathToString(path);
AssetIDValue* id_value = new AssetIDValue{{}, asset_id};
atomic_value_map_set(m_path_to_asset_id, key.data(), key.size(), &id_value->node);
}
value = new AssetMapValue{{}, std::move(asset_path_map)};
atomic_value_map_set(m_asset_id_to_asset_map_path, asset_id.data(), asset_id.size(),
&value->node);
}
void DirectFilesystemAssetLibrary::PathModified(std::string_view path)
{
AssetID asset_id;
bool found = false;
atomic_value_map_enter(m_path_to_asset_id);
const AssetIDValue* value = reinterpret_cast<const AssetIDValue*>(
atomic_value_map_get(m_path_to_asset_id, path.data(), path.size()));
if (value)
{
asset_id = value->asset_id;
found = true;
}
atomic_value_map_exit(m_path_to_asset_id);
if (found)
{
auto& system = Core::System::GetInstance();
auto& resource_manager = system.GetCustomResourceManager();
resource_manager.MarkAssetDirty(asset_id);
}
}
VideoCommon::Assets::AssetMap
DirectFilesystemAssetLibrary::GetAssetMapForID(const AssetID& asset_id) const
{
VideoCommon::Assets::AssetMap result;
atomic_value_map_enter(m_asset_id_to_asset_map_path);
const AssetMapValue* value = reinterpret_cast<const AssetMapValue*>(
atomic_value_map_get(m_asset_id_to_asset_map_path, asset_id.data(), asset_id.size()));
if (value)
result = value->map;
atomic_value_map_exit(m_asset_id_to_asset_map_path);
return result;
}
} // namespace VideoCommon