#pragma once #include "../../Auxiliary/types.hpp" #include "../cd_file_types.hpp" namespace JabyEngine { namespace FileProcessor { class State { public: struct Reserved { uint32_t reserved[8]; }; struct Configuration; template using GenericProcessRoutine = Progress (*)(Configuration&, T&); typedef GenericProcessRoutine ProcessRoutine; // TODO: Better name!!!! struct Configuration { ProcessRoutine process_routine = nullptr; const uint8_t* data_adr = nullptr; size_t data_bytes = 0ull; template static __always_inline Configuration from(GenericProcessRoutine process_routine, const uint8_t* data_adr) { return {reinterpret_cast(process_routine), data_adr}; } template T simple_read_r() { static constexpr size_t T_SIZE = sizeof(T); T value = *reinterpret_cast(this->data_adr); Configuration::processed(T_SIZE); return value; } constexpr void processed(size_t bytes) { this->data_adr += bytes; this->data_bytes -= bytes; } constexpr void skip(size_t bytes) { Configuration::processed(bytes); } }; Configuration config; Reserved reserved; template static __always_inline State from(const T& state, const uint32_t* data_adr, GenericProcessRoutine process_routine) { return {Configuration::from(process_routine, reinterpret_cast(data_adr)), *reinterpret_cast(&state)}; static_assert(sizeof(T) <= sizeof(Reserved)); } public: Progress process(size_t bytes_ready) { this->config.data_bytes += bytes_ready; return (*this->config.process_routine)(this->config, this->reserved); } }; // The nothing state State create(const uint32_t* data_adr, const Nothing& nothing); State create(const uint32_t* data_adr, const SimpleTIM& file); State create(const uint32_t* data_adr, const TIM& file); State create(const uint32_t* data_adr, const VAG& file); State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload); } }