blob: bc5219d1e379a9f55c6525b42f034b5459d6ecf9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#pragma once
#include <tsl/array_map.h>
#include <filesystem>
#include <iosfwd>
#include <memory>
#include <string_view>
/// A structure representing a ready-to-be-loaded asset, locating on the disk.
struct SavedAsset
{
std::filesystem::path Path;
std::string Name;
/// `Path`'s string form, encoded in UTF-8.
std::string PathString = Path.string();
};
class Asset
{
public:
Asset();
virtual ~Asset() = default;
};
class AssetCategory
{
public:
virtual ~AssetCategory() = default;
virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const = 0;
virtual Asset* CreateEmpty(const SavedAsset& diskForm) const = 0;
std::unique_ptr<Asset> CreateEmptyUnique(const SavedAsset& diskForm) const;
virtual Asset* Load(const SavedAsset& diskForm) const = 0;
std::unique_ptr<Asset> LoadUnique(const SavedAsset& diskForm) const;
/// This should call ImGui::BeginTable() along with other accessories such as setting up the header row.
virtual void SetupDetailsTable(const char* tableId) const = 0;
virtual void DrawBigIcon(const SavedAsset& asset) const = 0;
virtual void DrawDetailsTableRow(const SavedAsset& asset) const = 0;
protected:
/* Helper loader functions */
static void DiscoverFilesByExtension(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, std::string_view extension);
static void DiscoverFilesByHeader(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, const std::function<bool(std::istream&)>& validater);
};
class AssetList
{
private:
const AssetCategory* mLoader;
tsl::array_map<char, SavedAsset> mAssets;
tsl::array_map<char, std::unique_ptr<Asset>> mCache;
int mCacheSizeLimit = 0;
public:
AssetList(const AssetCategory& loader);
// TODO support file watches
void Reload();
const SavedAsset* FindByName(std::string_view name) const;
const SavedAsset& Create(SavedAsset asset);
std::unique_ptr<Asset> CreateAndLoad(SavedAsset asset);
std::unique_ptr<Asset> LoadFromDisk(std::string_view name) const;
bool Rename(std::string_view oldName, std::string_view newName);
bool Remove(std::string_view name);
int GetCacheSizeLimit() const;
void SetCacheSizeLimit(int limit);
struct DrawState
{
const SavedAsset* SelectedAsset = nullptr;
};
void DrawBigIcons(DrawState& state);
void DrawDetails(DrawState& state);
};
template <class TAsset>
class TypedAssetList : public AssetList
{
public:
using Asset = TAsset;
using AssetType = typename TAsset::CategoryType;
public:
// Import constructor
using AssetList::AssetList;
Asset* FindByName(std::string_view name) const
{
return static_cast<TAsset*>(AssetList::FindByName(name));
}
std::unique_ptr<Asset> Create(std::string_view name)
{
return std::unique_ptr<TAsset>(static_cast<TAsset*>(AssetList::Create(name).release()));
}
std::unique_ptr<Asset> LoadFromDisk(std::string_view name) const
{
return std::unique_ptr<TAsset>(static_cast<TAsset>(AssetList::LoadFromDisk(name)));
}
};
|