CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
ResourceStream.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Forward.hpp"
11
12#include "ResourceHandle.hpp"
13
15
19
20namespace CeresEngine {
21
24 struct ResourceStreamID : public UUID {
25 using UUID::UUID;
26
28 explicit ResourceStreamID(const UUID& uuid) : UUID(uuid) {}
29
31 static const ResourceStreamID null;
32 };
33
35
38 enum class ResourceStreamFlag {
42 Seekable = (1u << 0u),
43
45 Compressible = (1u << 1u),
46
48 Default = 0,
49 };
50
54
59
63
70
74
75 // ---------------------------------------------------------------------------------------------
76
77
82 bool isSeekable : 1 = false;
83
86 bool allowCompression : 1 = true;
87
90 UInt64 sizeHint = 0;
91 };
92
96
99 private:
101 using ScopedLock = ResourceStreamLockMutex::Lock;
102
106
109
110 public:
114
115 public:
117 [[nodiscard]] bool isExclusive() const noexcept { return mScopedLock.isExclusive(); }
118
121 CE_ASSERT(mData != nullptr);
122 return *mData;
123 }
124 };
125
129 class ResourceStreamData : public RefCounted<ResourceStreamData> {
130 public:
133
137
140
141 private:
144
145 public:
152
155
156 public:
159
162
163 public:
168
171
172 protected:
176 struct Awaitable : public super {
177 ResourceStreamData& streamData;
178
179 explicit Awaitable(super&& other, ResourceStreamData& streamData) : super(std::move(other)), streamData(streamData) {
180 }
181
182 [[nodiscard]] ResourceStreamLock await_resume() noexcept { return ResourceStreamLock{streamData, super::await_resume()}; }
183 };
184 return Awaitable{mMutex.lock_shared(), *this};
185 }
186
190 struct Awaitable : public super {
191 ResourceStreamData& streamData;
192
193 explicit Awaitable(super&& other, ResourceStreamData& streamData) : super(std::move(other)), streamData(streamData) {
194 }
195
196 [[nodiscard]] ResourceStreamLock await_resume() noexcept { return ResourceStreamLock{streamData, super::await_resume()}; }
197 };
198 return Awaitable{mMutex.lock(), *this};
199 }
200 };
201
204
205 // ---------------------------------------------------------------------------------------------
206 // ---------------------------------------------------------------------------------------------
207
209 class ResourceStream : public virtual IStream {
210 private:
213
214 public:
216
217 public:
220
223 };
224
225 // ---------------------------------------------------------------------------------------------
226
228 class IResourceInputStream : public virtual ResourceStream, public virtual IInputStream {
230
231 public:
232 using super::super;
233 };
234
236 class ResourceInputStream : public Poly<IResourceInputStream, sizeof(void*), false> {
237 using super = Poly<IResourceInputStream, sizeof(void*), false>;
238
239 public:
240 using super::super;
242
244 explicit operator InputStream() { return InputStream(dynamic_cast<IInputStream*>(get())); }
245 };
246
247 // ---------------------------------------------------------------------------------------------
248
250 class IResourceOutputStream : public virtual ResourceStream, public virtual IOutputStream {
252
253 private:
255
256 public:
257 using super::super;
258 };
259
261 class ResourceOutputStream : public Poly<IResourceOutputStream, sizeof(void*), false> {
262 using super = Poly<IResourceOutputStream, sizeof(void*), false>;
263
264 public:
265 using super::super;
267
269 explicit operator OutputStream() { return OutputStream(dynamic_cast<IOutputStream*>(get())); }
270 };
271
272 // ---------------------------------------------------------------------------------------------
273
276 private:
278
279 public:
281
282 public:
285
288
289 public: // IDataStream interface
291 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept override {
292 CE_ASSERT(mStream != nullptr);
293 return mStream->isSeekable(mode);
294 }
295
297 void seek(const std::streamsize position, const Seek mode = Seek::Start) override {
298 CE_ASSERT(mStream != nullptr);
299 mStream->seek(position, mode);
300 }
301
303 [[nodiscard]] bool isTellable() const noexcept override {
304 CE_ASSERT(mStream != nullptr);
305 return mStream->isTellable();
306 }
307
309 [[nodiscard]] size_t tell() override {
310 CE_ASSERT(mStream != nullptr);
311 return mStream->tell();
312 }
313
315 [[nodiscard]] bool isSizeKnown() const noexcept override {
316 CE_ASSERT(mStream != nullptr);
317 return mStream->isSizeKnown();
318 }
319
321 [[nodiscard]] size_t size() override {
322 CE_ASSERT(mStream != nullptr);
323 return mStream->size();
324 }
325
326 public:
328 [[nodiscard]] bool isReadable() const noexcept override {
329 CE_ASSERT(mStream != nullptr);
330 return mStream->isReadable();
331 }
332
334 [[nodiscard]] size_t read(void* data, const size_t n) override {
335 CE_ASSERT(mStream != nullptr);
336 return mStream->read(data, n);
337 }
338
340 [[nodiscard]] bool invalidate() override {
341 CE_ASSERT(mStream != nullptr);
342 return mStream->invalidate();
343 }
344 };
345
348 private:
350
351 public:
353
354 public:
357
360
361 public: // IDataStream interface
363 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept override {
364 CE_ASSERT(mStream != nullptr);
365 return mStream->isSeekable(mode);
366 }
367
369 void seek(const std::streamsize position, const Seek mode = Seek::Start) override {
370 CE_ASSERT(mStream != nullptr);
371 mStream->seek(position, mode);
372 }
373
375 [[nodiscard]] bool isTellable() const noexcept override {
376 CE_ASSERT(mStream != nullptr);
377 return mStream->isTellable();
378 }
379
381 [[nodiscard]] size_t tell() override {
382 CE_ASSERT(mStream != nullptr);
383 return mStream->tell();
384 }
385
387 [[nodiscard]] bool isSizeKnown() const noexcept override {
388 CE_ASSERT(mStream != nullptr);
389 return mStream->isSizeKnown();
390 }
391
393 [[nodiscard]] size_t size() override {
394 CE_ASSERT(mStream != nullptr);
395 return mStream->size();
396 }
397
398 public:
400 [[nodiscard]] bool isWritable() const noexcept override {
401 CE_ASSERT(mStream != nullptr);
402 return mStream->isWritable();
403 }
404
406 [[nodiscard]] size_t write(const void* data, const size_t n) override {
407 CE_ASSERT(mStream != nullptr);
408 return mStream->write(data, n);
409 }
410
412 [[nodiscard]] bool flush() override {
413 CE_ASSERT(mStream != nullptr);
414 return mStream->flush();
415 }
416 };
417
418 // ---------------------------------------------------------------------------------------------
419 // ---------------------------------------------------------------------------------------------
420
482
483 // ---------------------------------------------------------------------------------------------
484
507
508} // namespace CeresEngine
509
#define CE_FLAGS_OPERATORS(Enum)
Defines global operators for a Flags<Enum, Storage> implementation.
Definition Flags.hpp:216
#define CE_ASSERT(...)
Definition Macros.hpp:323
A retain-release type of smart pointer.
Definition SmartPtr.hpp:132
A stream associated to a resource.
Definition ResourceStream.hpp:430
Async< ResourceOutputStream > openOutputStream()
Creates a new resource stream.
HResourceStream(const HResourceStream &)=delete
HResourceStream & operator=(const HResourceStream &)=delete
ResourceStreamDataPtr mData
The stream data pointer. If null, the stream is null.
Definition ResourceStream.hpp:436
HResourceStream(HResourceStream &&) noexcept=default
Async< ResourceInputStream > openInputStream() const
Opens a resource stream for reading.
A stream that provides read-only stream functionality.
Definition Stream.hpp:126
A stream that provides write-only stream functionality.
Definition Stream.hpp:233
A specialized InputStream for a ResourceStream.
Definition ResourceStream.hpp:228
A specialized OutputStream for a ResourceStream.
Definition ResourceStream.hpp:250
OutputStream mStream
Definition ResourceStream.hpp:254
An interface that all data streams must implement.
Definition Stream.hpp:58
Seek
An enumeration that describes how a data stream should be seeked.
Definition Stream.hpp:72
A ResourceStream stored fully in memory.
Definition ResourceStream.hpp:486
Async< ResourceOutputStream > openOutputStream() override
Async< ResourceInputStream > openInputStream() override
~InMemoryResourceStreamData() noexcept override=default
MemoryDataStream mStream
The backing data stream.
Definition ResourceStream.hpp:489
InMemoryResourceStreamData(ResourceData &resourceData, const ResourceStreamID &streamID, const ResourceStreamFlags &flags)
Creates a new InMemoryResourceStream for the given resource and with the given stream ID.
Definition ResourceStream.hpp:497
A stream that provides read-only stream functionality.
Definition Stream.hpp:210
A data stream that reads or writes data into a memory buffer.
Definition Stream.hpp:693
A stream that provides write-only stream functionality.
Definition Stream.hpp:307
A pointer type that has value semantics.
Definition Poly.hpp:57
IResourceInputStream * get()
Definition Poly.hpp:367
A simple reference counter base class.
Definition SmartPtr.hpp:438
An object, provided by the resource manager, to view and alter data from the resource itself.
Definition Resource.hpp:89
Definition ResourceHandle.hpp:166
A base class that all resources must extend from.
Definition Resource.hpp:186
A specialized InputStream for a ResourceStream.
Definition ResourceStream.hpp:236
ResourceInputStream(ResourceStreamLock &&lock, InputStream &&stream)
The ResourceManager is the main class responsible for managing and handling all resources in the engi...
Definition ResourceManager.hpp:47
A specialized OutputStream for a ResourceStream.
Definition ResourceStream.hpp:261
ResourceOutputStream(ResourceStreamLock &&lock, OutputStream &&stream)
An object that allows storing side-band data for a resource.
Definition ResourceStream.hpp:129
virtual Async< ResourceOutputStream > openOutputStream()=0
virtual Async< ResourceInputStream > openInputStream()=0
const ResourceStreamFlags flags
A set of flags that determine the behavior of the resource stream.
Definition ResourceStream.hpp:139
virtual ~ResourceStreamData() noexcept=default
Destroys the resource stream data.
bool isCompressible() const noexcept
If defined, will indicate that the stream can be compressed.
Definition ResourceStream.hpp:170
const ResourceStreamID streamID
The resource stream ID.
Definition ResourceStream.hpp:136
auto acquireWriteLock()
Asynchronously acquires a write lock on the stream.
Definition ResourceStream.hpp:188
ResourceStreamLockMutex mMutex
A mutex that provides synchronized access to the resource stream.
Definition ResourceStream.hpp:143
bool isSeekable() const noexcept
If defined, indicates that returned stream must be seekable.
Definition ResourceStream.hpp:167
ResourceData & resourceData
A handle to the resource that owns the stream.
Definition ResourceStream.hpp:132
ResourceStreamData(ResourceData &resourceData, const ResourceStreamID &streamID, const ResourceStreamFlags &flags)
Creates a new ResourceStreamData for the given resource and with the given stream ID.
auto acquireReadLock()
Asynchronously acquires a read lock on the stream.
Definition ResourceStream.hpp:174
A base class for InputStream and OutputStream of a ResourceStream.
Definition ResourceStream.hpp:209
ResourceStreamLock mStreamLock
A lock acquired for the stream. Must be kept for as long as the stream is open.
Definition ResourceStream.hpp:212
HResource getResource() const
Gets the resource to which this stream belongs to.
ResourceStream(ResourceStreamLock &&lock)
Definition ResourceStream.hpp:215
ResourceManager * getResourceManager() const
Gets the resource manager of the resource that owns the stream.
A lock that allows either reading or writing to the stream.
Definition ResourceStream.hpp:98
ResourceStreamDataPtr mData
The resource stream data instance to which this lock corresponds to.
Definition ResourceStream.hpp:108
ResourceStreamData & getStreamData() const noexcept
The resource stream data instance to which this lock corresponds to.
Definition ResourceStream.hpp:120
ScopedLock mScopedLock
The low-level scoped lock, usually acquired and managed from the owning ResourceStreamData instance.
Definition ResourceStream.hpp:105
ResourceStreamLock(ResourceStreamData &data, ScopedLock &&lock)
Creates a new ResourceStreamLock for the given resource stream and an acquired scoped lock.
Definition ResourceStream.hpp:113
bool isExclusive() const noexcept
Determines if the lock is exclusive (writing) or shared (reading).
Definition ResourceStream.hpp:117
ResourceStreamLockMutex::Lock ScopedLock
A type that represents the low-level scoped lock.
Definition ResourceStream.hpp:101
LockOperation lock_shared()
Locks the mutex in a shared state.
Definition AsyncMutex.hpp:312
friend class LockOperation
Definition AsyncMutex.hpp:269
LockOperation lock()
Locks the mutex in an exclusive state.
Definition AsyncMutex.hpp:315
A specialized InputStream for a ResourceStream.
Definition ResourceStream.hpp:275
void seek(const std::streamsize position, const Seek mode=Seek::Start) override
Changes the position of the data stream.
Definition ResourceStream.hpp:297
bool isReadable() const noexcept override
Checks if the stream is readable.
Definition ResourceStream.hpp:328
const InputStream & getInputStream() const noexcept
Definition ResourceStream.hpp:287
bool isTellable() const noexcept override
Checks if the stream knows it's current absolute position.
Definition ResourceStream.hpp:303
bool isSizeKnown() const noexcept override
Checks if the stream knows the size of the data.
Definition ResourceStream.hpp:315
InputStream & getInputStream() noexcept
Definition ResourceStream.hpp:284
WrappedResourceInputStream(ResourceStreamLock &&lock, InputStream &&stream)
Definition ResourceStream.hpp:280
bool isSeekable(const Seek mode=Seek::Start) const noexcept override
Checks if the stream is seekable.
Definition ResourceStream.hpp:291
bool invalidate() override
In the stream is buffered, invalidates any buffered read data from the stream.
Definition ResourceStream.hpp:340
size_t tell() override
Gets the absolute stream position, in bytes.
Definition ResourceStream.hpp:309
InputStream mStream
Definition ResourceStream.hpp:277
size_t read(void *data, const size_t n) override
Reads data from the data stream to a buffer of raw memory data with length n.
Definition ResourceStream.hpp:334
size_t size() override
Gets the number of bytes available on the stream.
Definition ResourceStream.hpp:321
A specialized OutputStream for a ResourceStream.
Definition ResourceStream.hpp:347
bool isWritable() const noexcept override
Definition ResourceStream.hpp:400
bool flush() override
Definition ResourceStream.hpp:412
bool isSeekable(const Seek mode=Seek::Start) const noexcept override
Checks if the stream is seekable.
Definition ResourceStream.hpp:363
size_t write(const void *data, const size_t n) override
Definition ResourceStream.hpp:406
bool isTellable() const noexcept override
Checks if the stream knows it's current absolute position.
Definition ResourceStream.hpp:375
OutputStream & getDataStream() noexcept
Definition ResourceStream.hpp:356
bool isSizeKnown() const noexcept override
Checks if the stream knows the size of the data.
Definition ResourceStream.hpp:387
void seek(const std::streamsize position, const Seek mode=Seek::Start) override
Changes the position of the data stream.
Definition ResourceStream.hpp:369
WrappedResourceOutputStream(ResourceStreamLock &&lock, OutputStream &&stream)
Definition ResourceStream.hpp:352
const OutputStream & getDataStream() const noexcept
Definition ResourceStream.hpp:359
OutputStream mStream
Definition ResourceStream.hpp:349
size_t size() override
Gets the number of bytes available on the stream.
Definition ResourceStream.hpp:393
size_t tell() override
Gets the absolute stream position, in bytes.
Definition ResourceStream.hpp:381
Definition Application.hpp:19
std::uint64_t UInt64
Definition DataTypes.hpp:26
decltype(auto) lock(Func &&func, Ts &... objects)
Definition Threading.hpp:667
ResourceStreamWriteFlag
Definition ResourceStream.hpp:64
cti::continuable< Args... > Async
Defines a non-copyable continuation type which uses the function2 backend for type erasure.
Definition Async.hpp:22
ResourceStreamFlag
A set of flags that can be given when creating a new resource stream.
Definition ResourceStream.hpp:38
@ Seekable
If defined, indicates that returned stream must be seekable.
@ Compressible
If defined, will indicate that the stream can be compressed.
auto move(Vector3 position)
Moves a entity to the given position.
Definition Helpers.hpp:22
@ Truncate
Truncate the file if it exists.
ResourceStreamReadFlag
Definition ResourceStream.hpp:55
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
RC< ResourceStreamData > ResourceStreamDataPtr
A base class for InputStream and OutputStream of a ResourceStream.
Definition Forward.hpp:37
Definition Span.hpp:668
Wrapper around an enum that allows simple use of bitwise logic operations.
Definition Flags.hpp:19
constexpr bool isSet(Enum value) const noexcept
Checks whether all of the provided bits are set.
Definition Flags.hpp:54
A structure that describes the creation of a resource stream.
Definition ResourceStream.hpp:78
bool allowCompression
If defined, will indicate that the stream can be compressed by the implementation.
Definition ResourceStream.hpp:86
bool isSeekable
If defined, indicates that returned stream must be seekable.
Definition ResourceStream.hpp:82
Type that uniquely represents a stream in the resource system.
Definition ResourceStream.hpp:24
ResourceStreamID(const UUID &uuid)
Converts a raw UUID into a ResourceStreamID.
Definition ResourceStream.hpp:28
static const ResourceStreamID null
A null (or empty) resource ID.
Definition ResourceStream.hpp:31
Represents a universally unique identifier (UUID).
Definition UUID.hpp:27
constexpr UUID()=default
Initializes an empty UUID.