载入中...
搜索中...
未找到
PreparedFile.cpp
浏览该文件的文档.
2#include <simplesquirrel/simplesquirrel.hpp>
3#include "common/AsyncWork.h"
4#include "common/Capability.h"
5#include "common/Exception.h"
6#include "common/Resource.h"
10
11namespace eve::filesystem {
12namespace {
13constexpr size_t maximumBytes = 1024ull * 1024 * 1024;
14constexpr std::string_view suffix = "?filedata=1";
15class FileSnapshot final : public Resource {
16public:
17 std::shared_ptr<const FileData> bytes;
18 FileSnapshot(std::string key, std::shared_ptr<const FileData> data)
19 : Resource(std::move(key)), bytes(std::move(data)) {}
20 void adopt(Resource& replacement) override { bytes.swap(static_cast<FileSnapshot&>(replacement).bytes); }
21};
22class Loader final : public caps::IAssetReloader {
23public:
24 const char* reloadKind() const override { return "filedata"; }
25 bool handlesPath(const std::string& key) const override { return key.ends_with(suffix); }
26 Result<bool> reload(const std::string&) override { return Result<bool>::success(false); }
27 Resource* load(const std::string& key) override {
28 auto* fs = ModuleManager::getInstance<Filesystem>("Filesystem");
29 if (!fs) throw Exception("Initialize Filesystem before reading prepared files");
31 Filesystem::Info info{};
32 if (!fs->getInfo(path, info) || info.size <= 0 || uint64_t(info.size) > maximumBytes)
33 throw Exception("Prepared file missing or exceeds 1 GiB: %s", path.c_str());
34 std::shared_ptr<const FileData> bytes(fs->read(path));
35 if (!bytes || bytes->getSize() == 0 || bytes->getSize() > maximumBytes)
36 throw Exception("Prepared file read failed: %s", path.c_str());
37 return new FileSnapshot(key, std::move(bytes));
38 }
39};
40Loader loader;
41struct Register {
42 Register() { cap::addListener<caps::IAssetReloader>(&loader, caps::IAssetReloader::kCache - 1); }
43} registration;
44std::string keyFor(const std::string& path) {
45 if (path.empty() || path.find('?') != std::string::npos) throw Exception("Invalid prepared file path");
46 return ResourceManager::makeKey(path, "filedata=1");
47}
48} // namespace
50 if (!cap::query<caps::IAsyncWorkExecutor>() || !ModuleManager::getInstance<Filesystem>("Filesystem"))
52 "File preparation requires Filesystem and a worker executor"));
53 try {
55 } catch (const std::exception& e) {
57 }
58}
61 try {
62 if (!limit || limit > maximumBytes)
63 return R::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "Invalid prepared file size limit"));
64 auto result = ResourceManager::getInstance().waitFor(keyFor(path));
65 if (!result) return R::failure(result.status());
66 auto bytes = static_cast<FileSnapshot&>(result.value().get()).bytes;
67 if (bytes->getSize() > limit)
68 return R::failure(
69 Diagnostic::error(DiagnosticCode::InvalidArgument, "Prepared file exceeds caller size limit", path));
70 return R::success(std::move(bytes));
71 } catch (const std::exception& e) {
72 return R::failure(Diagnostic::error(DiagnosticCode::Failed, e.what(), path));
73 }
74}
76 cls.addFunc("requestPreparedFile", [vm = cls.getHandle()](Filesystem*, const std::string& path) {
77 return script::projectResult(vm, requestPreparedFile(path));
78 });
79}
80} // namespace eve::filesystem
Capability for submitting CPU work onto a worker pool.
HSQUIRRELVM vm
Definition ECS.cpp:20
HSQOBJECT cls
Definition ECS.cpp:21
std::uint32_t key
std::uint64_t bytes
std::string path
Definition PlayHost.cpp:110
The single Squirrel projection for common Result, Status and Value.
int limit
Definition TreeMesh.cpp:164
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
ResultRef< Resource > waitFor(std::string key)
Block until key is cached, failed, or unclaimed.
Definition Resource.cpp:226
eve::Result< void > request(std::string key)
Queue a cache miss load without blocking for decode to finish.
Definition Resource.cpp:149
static std::string pathOfKey(const std::string &key)
The path part of a cache key (everything before the first '?').
Definition Resource.cpp:46
static std::string makeKey(const std::string &path, const std::string &query="")
Build a cache key from a path and optional ?query parameters.
Definition Resource.cpp:37
static ResourceManager & getInstance()
Returns the instance.
Definition Resource.cpp:15
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
EVENGINE_API_FOUNDATION public API.
Definition Filesystem.h:43
void exposePreparedFileBindings(ssq::Class &cls)
Install game-thread script submission bindings; retains no class borrow.
Result< void > requestPreparedFile(const std::string &path)
Queue immutable file bytes in the canonical ResourceManager cache.
Result< std::shared_ptr< const FileData > > readPreparedFile(const std::string &path, size_t limit)
Join a queued read or synchronously read an immutable file snapshot.
glm::uvec4 info