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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#pragma once
#include "Utils/UUID.hpp"
#include "cplt_fwd.hpp"
#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.
/// Each asset should be identified by a unique uuid within the asset category (i.e. a workflow and a template can share the same uuid),
/// generated on insertion to an asset list if not given by the caller.
struct SavedAsset
{
std::string Name;
/// UUID of this asset. This field is generated as a random UUID v4 upon insertion into an AssetList, if not already provided by the caller (indicated by !is_nil()).
uuids::uuid Uuid;
/// Extra data to be used by the AssetList/Asset implementation.
uint64_t Payload;
template <class TProxy>
void OperateIOProxy(TProxy& proxy);
};
class Asset
{
public:
Asset();
virtual ~Asset() = default;
};
enum class NameSelectionError
{
None,
Duplicated,
Empty,
};
class AssetList
{
private:
class Private;
std::unique_ptr<Private> mPrivate;
public:
AssetList(Project& project);
virtual ~AssetList();
Project& GetConnectedProject() const;
// TODO support file watches
void Reload();
int GetCount() const;
// TODO convert to custom iterable
const tsl::array_map<char, SavedAsset>& GetAssets() const;
const SavedAsset* FindByName(std::string_view name) const;
const SavedAsset& Create(SavedAsset asset);
std::unique_ptr<Asset> CreateAndLoad(SavedAsset asset);
/// Load the asset on disk by its name.
std::unique_ptr<Asset> Load(std::string_view name) const;
/// Load the asset on disk by a reference to its SavedAsset instance. This function assumes that the given SavedAsset
/// is stored in AssetList, otherwise the behavior is undefined.
std::unique_ptr<Asset> Load(const SavedAsset& asset) const;
const SavedAsset* Rename(std::string_view oldName, std::string_view newName);
bool Remove(std::string_view name);
int GetCacheSizeLimit() const;
void SetCacheSizeLimit(int limit);
struct ListState
{
const SavedAsset* SelectedAsset = nullptr;
};
void DisplayIconsList(ListState& state);
void DisplayDetailsList(ListState& state);
void DisplayControls(ListState& state);
protected:
virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const = 0;
// Helper
void DiscoverFilesByExtension(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, std::string_view extension) const;
void DiscoverFilesByHeader(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, const std::function<bool(std::istream&)>& validater) const;
/// Create an empty/default instance of this asset type on disk, potentially qualified by SavedAsset::Payload.
/// Return `true` on success and `false` on failure.
virtual bool SaveInstance(const SavedAsset& assetInfo, const Asset* asset) const = 0;
/// The returned pointer indicate ownership to the object.
virtual Asset* LoadInstance(const SavedAsset& assetInfo) const = 0;
/// Create an empty/default instance of this asset type, potentially qualified by SavedAsset::Payload.
/// The returned pointer indicate ownership to the object.
virtual Asset* CreateInstance(const SavedAsset& assetInfo) const = 0;
virtual bool RenameInstanceOnDisk(const SavedAsset& assetInfo, std::string_view oldName) const = 0;
virtual std::string RetrieveNameFromFile(const std::filesystem::path& file) const = 0;
virtual uuids::uuid RetrieveUuidFromFile(const std::filesystem::path& file) const = 0;
virtual std::filesystem::path RetrievePathFromAsset(const SavedAsset& asset) const = 0;
virtual void DisplayAssetCreator(ListState& state) = 0;
virtual void DisplayDetailsTable(ListState& state) const = 0;
};
template <class T>
class AssetListTyped : public AssetList
{
public:
using AssetList::AssetList;
#pragma clang diagnostic push
#pragma ide diagnostic ignored "HidingNonVirtualFunction"
std::unique_ptr<T> CreateAndLoad(SavedAsset asset)
{
return std::unique_ptr<T>(static_cast<T*>(AssetList::CreateAndLoad(asset).release()));
}
std::unique_ptr<T> Load(std::string_view name) const
{
return std::unique_ptr<T>(static_cast<T*>(AssetList::Load(name).release()));
}
std::unique_ptr<T> Load(const SavedAsset& asset) const
{
return std::unique_ptr<T>(static_cast<T*>(AssetList::Load(asset).release()));
}
#pragma clang diagnostic pop
};
|