Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
64e1555d56 | |||
a65c8d64b5 | |||
fa2b801690 | |||
4e887b1ac2 | |||
126fc92fae | |||
2ef28273b0 | |||
04bf7d43ff | |||
fb86dca332 | |||
7e380efd7d | |||
b5e05864b6 | |||
e2e5a1b8db | |||
2a2296685e | |||
0b298c6130 | |||
f030ac62ae | |||
2734cc00fb | |||
3196c5021e | |||
72347ea9a2 | |||
d13fe81ac5 | |||
beba947c69 | |||
405acb026f | |||
58f624a18a | |||
93f881cf03 | |||
54012df3a1 | |||
27dfd430ad | |||
b4674bd94c | |||
1fd9c63cfe | |||
7cdd57cc5f | |||
b1adf15f89 | |||
8e88412deb | |||
7a79fa4d76 | |||
d3c1e81a27 | |||
54065f6ce3 | |||
d394ca8445 |
@@ -42,7 +42,7 @@ set(EHS_SOURCES
|
||||
src/EHS.cpp include/ehs/EHS.h
|
||||
src/Type.cpp include/ehs/Type.h
|
||||
src/BaseObj.cpp include/ehs/BaseObj.h
|
||||
src/GarbageCollector.cpp include/ehs/GarbageCollector.h
|
||||
src/GC.cpp include/ehs/GC.h
|
||||
src/Log.cpp include/ehs/Log.h
|
||||
src/URI.cpp include/ehs/URI.h
|
||||
src/Math.cpp include/ehs/Math.h
|
||||
@@ -82,7 +82,7 @@ set(EHS_SOURCES
|
||||
include/ehs/ShdPtr.h
|
||||
include/ehs/WkPtr.h
|
||||
|
||||
src/database/DVar.cpp include/ehs/database/DVar.h
|
||||
src/db/DbVarTmpl.cpp include/ehs/db/DbVarTmpl.h
|
||||
|
||||
src/system/CPU.cpp include/ehs/system/CPU.h
|
||||
src/system/Thread.cpp include/ehs/system/Thread.h
|
||||
@@ -122,7 +122,7 @@ set(EHS_SOURCES
|
||||
|
||||
src/io/socket/Request.cpp include/ehs/io/socket/Request.h
|
||||
src/io/socket/Response.cpp include/ehs/io/socket/Response.h
|
||||
src/io/socket/DNS.cpp include/ehs/io/socket/DNS.h
|
||||
src/io/socket/BaseDNS.cpp include/ehs/io/socket/BaseDNS.h
|
||||
src/io/socket/BaseUDP.cpp include/ehs/io/socket/BaseUDP.h
|
||||
src/io/socket/BaseTCP.cpp include/ehs/io/socket/BaseTCP.h
|
||||
src/io/socket/SSL.cpp include/ehs/io/socket/SSL.h
|
||||
@@ -133,6 +133,7 @@ set(EHS_SOURCES
|
||||
include/ehs/io/socket/Socket.h
|
||||
include/ehs/io/socket/TCP.h
|
||||
include/ehs/io/socket/UDP.h
|
||||
include/ehs/io/socket/DNS.h
|
||||
|
||||
src/io/audio/Audio.cpp include/ehs/io/audio/Audio.h
|
||||
src/io/audio/BaseAudioDevice.cpp include/ehs/io/audio/BaseAudioDevice.h
|
||||
@@ -144,14 +145,14 @@ set(EHS_SOURCES
|
||||
src/io/img/PNG_Chunk.cpp include/ehs/io/img/PNG_Chunk.h
|
||||
src/io/img/ImgCodec.cpp include/ehs/io/img/ImgCodec.h
|
||||
|
||||
include/ehs/io/model/Vertex.h
|
||||
src/io/model/Mesh.cpp include/ehs/io/model/Mesh.h
|
||||
src/io/model/Bone.cpp include/ehs/io/model/Bone.h
|
||||
src/io/model/Model.cpp include/ehs/io/model/Model.h
|
||||
src/io/model/Animation.cpp include/ehs/io/model/Animation.h
|
||||
src/io/model/AnimBone.cpp include/ehs/io/model/AnimBone.h
|
||||
src/io/model/KeyFrame.cpp include/ehs/io/model/KeyFrame.h
|
||||
src/io/model/PropertyChange.cpp include/ehs/io/model/PropertyChange.h
|
||||
include/ehs/io/mdl/Vertex.h
|
||||
src/io/model/Mesh.cpp include/ehs/io/mdl/Mesh.h
|
||||
src/io/model/Bone.cpp include/ehs/io/mdl/Bone.h
|
||||
src/io/model/Mdl.cpp include/ehs/io/mdl/Mdl.h
|
||||
src/io/model/Animation.cpp include/ehs/io/mdl/Animation.h
|
||||
src/io/model/AnimBone.cpp include/ehs/io/mdl/AnimBone.h
|
||||
src/io/model/KeyFrame.cpp include/ehs/io/mdl/KeyFrame.h
|
||||
src/io/model/PropertyChange.cpp include/ehs/io/mdl/PropertyChange.h
|
||||
|
||||
src/io/hid/ButtonState.cpp include/ehs/io/hid/ButtonState.h
|
||||
src/io/hid/Button.cpp include/ehs/io/hid/Button.h
|
||||
@@ -160,12 +161,29 @@ set(EHS_SOURCES
|
||||
src/io/hid/HID.cpp include/ehs/io/hid/HID.h
|
||||
src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h
|
||||
src/io/hid/Input.cpp include/ehs/io/hid/Input.h
|
||||
src/io/model/MdlCodec.cpp
|
||||
include/ehs/io/mdl/MdlCodec.h
|
||||
include/ehs/io/UsbBase.h
|
||||
src/io/UsbBase.cpp
|
||||
include/ehs/db/DbTable.h
|
||||
include/ehs/db/DbObject.h
|
||||
include/ehs/db/DbVar.h
|
||||
src/db/DbVar.cpp
|
||||
include/ehs/db/Database.h
|
||||
src/db/DbObject.cpp
|
||||
src/db/Database.cpp
|
||||
src/db/Database.cpp
|
||||
src/db/DbTable.cpp
|
||||
include/ehs/io/BaseDirectory.h
|
||||
src/io/BaseDirectory.cpp
|
||||
include/ehs/io/Directory.h
|
||||
)
|
||||
|
||||
if (IS_OS_WINDOWS)
|
||||
list(APPEND EHS_SOURCES
|
||||
src/io/socket/UDP_W32.cpp include/ehs/io/socket/UDP_W32.h
|
||||
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
|
||||
src/io/socket/DNS_W32.cpp include/ehs/io/socket/DNS_W32.h
|
||||
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
|
||||
src/system/System_W32.cpp include/ehs/system/System_W32.h
|
||||
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
|
||||
@@ -176,11 +194,13 @@ if (IS_OS_WINDOWS)
|
||||
src/io/Window_W32.cpp include/ehs/io/Window_W32.h
|
||||
src/io/COM.cpp include/ehs/io/COM.h
|
||||
src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm
|
||||
src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h
|
||||
)
|
||||
elseif (IS_OS_LINUX)
|
||||
list(APPEND EHS_SOURCES
|
||||
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
|
||||
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
|
||||
src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h
|
||||
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
|
||||
src/system/System_LNX.cpp include/ehs/system/System_LNX.h
|
||||
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h
|
||||
@@ -190,13 +210,18 @@ elseif (IS_OS_LINUX)
|
||||
src/io/audio/AudioDevice_ALSA.cpp include/ehs/io/audio/AudioDevice_ALSA.h
|
||||
src/system/FileSystem.cpp include/ehs/system/FileSystem.h
|
||||
src/system/User.cpp include/ehs/system/User.h
|
||||
src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h
|
||||
src/io/Usb_LNX.cpp include/ehs/io/Usb_LNX.h
|
||||
)
|
||||
|
||||
set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
|
||||
|
||||
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
|
||||
add_compile_definitions(EHS_WS_WAYLAND)
|
||||
list(APPEND EHS_SOURCES src/io/xdg-shell-protocol.c include/ehs/io/xdg-shell-client-protocol.h src/io/Window_Way.cpp include/ehs/io/Window_Way.h)
|
||||
list(APPEND EHS_SOURCES
|
||||
src/io/xdg-shell-protocol.c include/ehs/io/xdg-shell-client-protocol.h
|
||||
src/io/xdg-decoration.c include/ehs/io/xdg-decoration.h
|
||||
src/io/Window_Way.cpp include/ehs/io/Window_Way.h)
|
||||
message("Building for Wayland.")
|
||||
elseif (LINUX_WINDOW_SYSTEM STREQUAL "XCB")
|
||||
add_compile_definitions(EHS_WS_XCB)
|
||||
|
@@ -8,6 +8,7 @@ This project does not fully follow the C++ standard.
|
||||
### Features
|
||||
- Audio IO/Processing/Manipulation
|
||||
- Image Processing/Manipulation
|
||||
- Databases
|
||||
- 3D Model & Mesh Processing/Manipulation
|
||||
- File IO
|
||||
- Basic File Monitoring
|
||||
@@ -20,7 +21,7 @@ This project does not fully follow the C++ standard.
|
||||
- Mutexes
|
||||
- Semaphores
|
||||
- CPU information and features at runtime
|
||||
- HTTP(S) Sockets
|
||||
- HTTP(S) Socket Layer
|
||||
- TCP Socket
|
||||
- UDP Socket
|
||||
- COM (Serial) IO
|
||||
@@ -29,12 +30,13 @@ This project does not fully follow the C++ standard.
|
||||
- Twitch Integration
|
||||
- Json Parsing/Writing
|
||||
- User Friendly HID Input
|
||||
- Basic Garbage Collector
|
||||
- Heap Garbage Collector
|
||||
- Linked List
|
||||
- Array
|
||||
- Vector
|
||||
- Asynchronous Task System
|
||||
- URI Parsing
|
||||
- USB (WIP)
|
||||
|
||||
### Supported Architectures
|
||||
- AMD64
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "EHS.h"
|
||||
#include "Vector.h"
|
||||
#include "BaseObj.h"
|
||||
#include "ehs/system/Mutex.h"
|
||||
@@ -10,10 +9,10 @@ namespace ehs
|
||||
{
|
||||
typedef bool (*GcLogic)(BaseObj*);
|
||||
|
||||
class GarbageCollector
|
||||
class GC
|
||||
{
|
||||
private:
|
||||
static Vector<GcLogic>* logic;
|
||||
static Array<GcLogic> logic;
|
||||
static Vector<BaseObj*> garbage;
|
||||
static UInt_64 max;
|
||||
static Thread thread;
|
||||
@@ -27,13 +26,17 @@ namespace ehs
|
||||
|
||||
static void Stop();
|
||||
|
||||
static bool HasLogic(GcLogic logicCb);
|
||||
|
||||
static bool AddLogic(GcLogic logicCb);
|
||||
|
||||
/// Adds an object to the garbage pile to be deleted.
|
||||
/// @param[in] obj The object to be deleted.
|
||||
static void Add(BaseObj* obj);
|
||||
|
||||
/// Sets the maximum amount of garbage to delete per poll.
|
||||
/// @param[in] newMax The new maximum.
|
||||
static void SetMax(const UInt_64 newMax);
|
||||
static void SetMax(UInt_64 newMax);
|
||||
|
||||
/// Gets the maximum amount of garbage to delete per poll.
|
||||
/// @returns The maximum.
|
||||
@@ -41,7 +44,7 @@ namespace ehs
|
||||
|
||||
/// Sets a new amount for memory pre-allocation to save on memory operations.
|
||||
/// @param[in] newStride The stride to pre-allocate.
|
||||
static void SetStride(const UInt_64 newStride);
|
||||
static void SetStride(UInt_64 newStride);
|
||||
|
||||
/// The amount of data pre-allocated to save on memory operations.
|
||||
/// @returns The stride.
|
||||
@@ -59,5 +62,8 @@ namespace ehs
|
||||
static void Dump();
|
||||
|
||||
static bool IsRunning();
|
||||
|
||||
private:
|
||||
static bool ShouldDelete(BaseObj *obj);
|
||||
};
|
||||
}
|
@@ -9,26 +9,53 @@
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Log;
|
||||
|
||||
typedef void (*LogRaisedCb)(const Log &);
|
||||
typedef void (*LogOutputCb)(const Array<Log> &);
|
||||
|
||||
enum class LogType : UInt_8
|
||||
{
|
||||
SUCCESS,
|
||||
ERR,
|
||||
WARN,
|
||||
INFO
|
||||
};
|
||||
|
||||
/// A helper class for holding error information and handling them.
|
||||
/// @tparam T The character data type to use.
|
||||
/// @tparam N The number data type to use.
|
||||
class Log
|
||||
{
|
||||
private:
|
||||
static void (*logCb)(const Log&);
|
||||
static void DefaultRaisedCb(const Log &log);
|
||||
|
||||
static void DefaultOutputCb(const Array<Log> &logs);
|
||||
|
||||
static LogRaisedCb raisedCb;
|
||||
static LogOutputCb outputCb;
|
||||
static Array<Log> logs;
|
||||
static Log lastLog;
|
||||
static bool immediate;
|
||||
LogType type;
|
||||
Array<Str_8> tags;
|
||||
UInt_64 code;
|
||||
Str_8 msg;
|
||||
|
||||
public:
|
||||
static void SetCallback(void (*newLogCb)(const Log&));
|
||||
static void SetRaisedCallback(LogRaisedCb newCb);
|
||||
|
||||
static void Raise(const Log& log);
|
||||
static void SetOutputCallback(LogOutputCb newCb);
|
||||
|
||||
static void OnExit();
|
||||
|
||||
static void Raise(Log log);
|
||||
|
||||
/// Retrieves the last log raised.
|
||||
static Log GetLastLog();
|
||||
|
||||
static void EnableImmediateMode(bool enable);
|
||||
|
||||
/// Default members initialization.
|
||||
Log();
|
||||
|
||||
@@ -36,22 +63,26 @@ namespace ehs
|
||||
/// @param [in] tags The tags to associate this log with.
|
||||
/// @param [in] code The unique code to use.
|
||||
/// @param [in] msg Detailed information about what happened.
|
||||
Log(std::initializer_list<Str_8> tags, const UInt_64 code, const Str_8& msg);
|
||||
Log(LogType type, const std::initializer_list<Str_8> &tags, UInt_64 code, Str_8 msg);
|
||||
|
||||
/// Initializes members with the given information.
|
||||
/// @param [in] tags The tags to associate this log with.
|
||||
/// @param [in] code The unique code to use.
|
||||
/// @param [in] msg Detailed information about what happened.
|
||||
Log(Array<Str_8>& tags, const UInt_64 code, const Str_8& msg);
|
||||
Log(LogType type, Array<Str_8> tags, UInt_64 code, Str_8 msg);
|
||||
|
||||
Log(Log &&log) noexcept;
|
||||
|
||||
/// Copies all members from the given log.
|
||||
/// @param [in] log The log to copy from.
|
||||
Log(const Log& log);
|
||||
Log(const Log &log);
|
||||
|
||||
Log &operator=(Log &&log) noexcept;
|
||||
|
||||
/// Copies all members from the given log.
|
||||
/// @param [in] log The log to copy from.
|
||||
/// @returns The log that has been assigned to.
|
||||
Log& operator=(const Log& log);
|
||||
Log &operator=(const Log &log);
|
||||
|
||||
/*
|
||||
/// Compares with another given log.
|
||||
@@ -65,24 +96,26 @@ namespace ehs
|
||||
bool operator!=(const Log log);
|
||||
*/
|
||||
|
||||
/// Checks whether or not this log has the given tags.
|
||||
/// @param [in] tags The tags to look for.
|
||||
/// @returns True if all tags were found, otherwise false.
|
||||
bool HasTags(const std::initializer_list<Str_8> tags) const;
|
||||
LogType GetType() const;
|
||||
|
||||
/// Checks whether or not this log has the given tags.
|
||||
/// @param [in] tags The tags to look for.
|
||||
/// @returns True if all tags were found, otherwise false.
|
||||
bool HasTags(const Array<Str_8>& tags) const;
|
||||
bool HasTags(const std::initializer_list<Str_8> &tags) const;
|
||||
|
||||
/// Checks whether or not this log has the given tags.
|
||||
/// @param [in] tags The tags to look for.
|
||||
/// @returns True if all tags were found, otherwise false.
|
||||
bool HasTags(const Array<Str_8> &tags) const;
|
||||
|
||||
/// Checks whether or not this log has the given tag.
|
||||
/// @param [in] tag The tag to look for.
|
||||
/// @returns True if tag was found, otherwise false.
|
||||
bool HasTag(const Str_8& tag) const;
|
||||
bool HasTag(const Str_8 &tag) const;
|
||||
|
||||
/// Retrieves all the tags.
|
||||
/// @returns The result.
|
||||
Array<Str_8> GetTags() const;
|
||||
const Array<Str_8> &GetTags() const;
|
||||
|
||||
UInt_64 GetCode() const;
|
||||
|
||||
@@ -101,16 +134,20 @@ namespace ehs
|
||||
|
||||
#ifndef EHS_LOG_INT
|
||||
#ifdef EHS_DEBUG
|
||||
#define EHS_LOG_INT(type, code, msg) Log::Raise({{type, GetAcronym_8(), EHS_FILE, EHS_FUNC, Str_8::FromNum((UInt_32)EHS_LINE)}, code, msg})
|
||||
#define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg})
|
||||
#else
|
||||
#define EHS_LOG_INT(type, code, msg) Log::Raise({{type, GetAcronym_8(), EHS_FUNC}, code, msg})
|
||||
#define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FUNC}, code, msg})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EHS_LOG
|
||||
#ifdef EHS_DEBUG
|
||||
#define EHS_LOG(type, code, msg) ehs::Log::Raise({{type, ehs::GetAppName_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg})
|
||||
#define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg})
|
||||
#else
|
||||
#define EHS_LOG(type, code, msg) ehs::Log::Raise({{type, ehs::GetAppName_8(), EHS_FUNC}, code, msg})
|
||||
#define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FUNC}, code, msg})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EHS_LOG_SUCCESS
|
||||
#define EHS_LOG_SUCCESS() ehs::Log::Raise({})
|
||||
#endif
|
@@ -101,29 +101,113 @@ namespace ehs
|
||||
return from * 57.295779513082320876798154814105;
|
||||
}
|
||||
|
||||
template <typename T = float>
|
||||
static T Exp(const T x)
|
||||
{
|
||||
T sum = 1;
|
||||
T term = 1;
|
||||
|
||||
for (int n = 1; n <= 20; ++n)
|
||||
{
|
||||
term *= x / n;
|
||||
sum += term;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <typename T = float>
|
||||
static T Ln_Taylor(T x)
|
||||
{
|
||||
T result = 0;
|
||||
T term = (x - 1) / (x + 1);
|
||||
T term_squared = term * term;
|
||||
T denominator = 1;
|
||||
T current_term = term;
|
||||
|
||||
for (int n = 0; n < 100; ++n)
|
||||
{
|
||||
result += current_term / denominator;
|
||||
current_term *= term_squared;
|
||||
denominator += 2;
|
||||
}
|
||||
|
||||
return 2 * result;
|
||||
}
|
||||
|
||||
template <typename T = float>
|
||||
static T Ln(T x)
|
||||
{
|
||||
if (x <= 0)
|
||||
return -1;
|
||||
|
||||
if (x == 1)
|
||||
return 0;
|
||||
|
||||
SSize exp = 0;
|
||||
while (x > 2)
|
||||
{
|
||||
x /= 2;
|
||||
exp++;
|
||||
}
|
||||
|
||||
while (x < 0.5)
|
||||
{
|
||||
x *= 2;
|
||||
exp--;
|
||||
}
|
||||
|
||||
T result = Ln_Taylor<T>(x);
|
||||
result += exp * Ln_Taylor<T>(2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// A method for use of exponents.
|
||||
/// @tparam T The data type to return;
|
||||
/// @tparam I The data type to use as the exponent.
|
||||
/// @param [in] from The value to use the exponent on.
|
||||
/// @param [in] of The exponent.
|
||||
/// @returns The result.
|
||||
template<typename T = float, typename I = UInt_64>
|
||||
static T Pow(const T from, const I of)
|
||||
template<typename T = float, typename I = float>
|
||||
static T Pow(const T base, const I exponent)
|
||||
{
|
||||
if (of < 0)
|
||||
{
|
||||
if (from == 0)
|
||||
return -0;
|
||||
if (base == 0)
|
||||
return (exponent == 0) ? 1 : 0;
|
||||
|
||||
return 1 / (from * Pow<T>(from, (-of) - 1));
|
||||
}
|
||||
if (exponent == 0)
|
||||
return 1;
|
||||
|
||||
if (of == 0)
|
||||
return 1;
|
||||
else if (of == 1)
|
||||
return from;
|
||||
SSize intExp = (SSize)exponent;
|
||||
bool isInteger = exponent == intExp;
|
||||
bool isNeg = base < 0;
|
||||
|
||||
return from * Pow<T>(from, of - 1);
|
||||
if (isNeg && isInteger)
|
||||
{
|
||||
T result = Exp<T>(exponent * Ln<T>(-base));
|
||||
if ((SSize)exponent % 2)
|
||||
result = -result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (isNeg && !isInteger)
|
||||
{
|
||||
T magnitude = Exp<T>(exponent * Ln<T>(-base));
|
||||
T angle = exponent * Pi<T>();
|
||||
T realPart = magnitude * Cos<T>(angle);
|
||||
T imagPart = magnitude * Sin<T>(angle);
|
||||
|
||||
return realPart;
|
||||
}
|
||||
|
||||
return Exp<T>(exponent * Ln<T>(base));
|
||||
}
|
||||
|
||||
template <typename T = float>
|
||||
static T Log10(const T x)
|
||||
{
|
||||
return Ln<T>(x) / Ln<T>(10);
|
||||
}
|
||||
|
||||
static float Near(const float from);
|
||||
|
@@ -130,7 +130,7 @@ namespace ehs
|
||||
case 3:
|
||||
return h;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Rectangle.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Rectangle.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,7 @@ namespace ehs
|
||||
case 3:
|
||||
return h;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Rectangle.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Rectangle.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ namespace ehs
|
||||
{
|
||||
if (index >= size)
|
||||
{
|
||||
EHS_LOG_INT("Warning", 0, "Cannot insert value at " + Str_8::FromNum(index) + " because it is outside of array range of " + size + ".");
|
||||
EHS_LOG_INT(LogType::WARN, 0, "Cannot insert value at " + Str_8::FromNum(index) + " because it is outside of array range of " + size + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -194,8 +194,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[this->size + remainder];
|
||||
|
||||
for (N i = 0; i < this->size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, this->size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -265,8 +264,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -336,8 +334,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -398,17 +395,87 @@ namespace ehs
|
||||
offset += sizeof(T) * value.Size();
|
||||
}
|
||||
|
||||
template<typename T, typename O = UInt_64>
|
||||
void WriteStr(const T* str, N inSize = 0)
|
||||
{
|
||||
bool sizeKnown = inSize;
|
||||
|
||||
if (!sizeKnown)
|
||||
while (str[inSize])
|
||||
inSize++;
|
||||
|
||||
N bSize = sizeof(T) * inSize;
|
||||
N bSizeN = bSize;
|
||||
if (!sizeKnown)
|
||||
bSizeN += sizeof(T);
|
||||
|
||||
if (bSizeN > size - offset)
|
||||
{
|
||||
N remainder = bSizeN - (size - offset);
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
size += remainder;
|
||||
}
|
||||
|
||||
if (CPU::GetEndianness() == Endianness::LE)
|
||||
{
|
||||
if (endianness == Endianness::LE)
|
||||
{
|
||||
Util::Copy(&data[offset], &str[0], bSize);
|
||||
|
||||
if (!sizeKnown)
|
||||
*(T*)&data[offset + inSize] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (N i = 0; i < inSize; ++i)
|
||||
for (N b = 0; b < sizeof(T); ++b)
|
||||
data[offset + sizeof(T) * i + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
||||
|
||||
if (!sizeKnown)
|
||||
*(T*)&data[offset + bSize] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (endianness == Endianness::LE)
|
||||
{
|
||||
for (N i = 0; i < inSize; ++i)
|
||||
for (N b = 0; b < sizeof(T); ++b)
|
||||
data[offset + sizeof(T) * i + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
||||
|
||||
if (!sizeKnown)
|
||||
*(T*)&data[offset + bSize] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Util::Copy(&data[offset], &str[0], bSize);
|
||||
|
||||
if (!sizeKnown)
|
||||
*(T*)&data[offset + bSize] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
offset += bSizeN;
|
||||
}
|
||||
|
||||
template<typename T, typename O = UInt_64>
|
||||
void WriteStr(const Str<T, O>& str)
|
||||
{
|
||||
if (sizeof(N) + sizeof(T) * str.Size() > size - offset)
|
||||
N inSize = sizeof(T) * (str.Size() + 1);
|
||||
|
||||
if (inSize > size - offset)
|
||||
{
|
||||
N remainder = sizeof(N) + sizeof(T) * str.Size() - (size - offset);
|
||||
N remainder = inSize - (size - offset);
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -419,54 +486,38 @@ namespace ehs
|
||||
{
|
||||
if (endianness == Endianness::LE)
|
||||
{
|
||||
*(N*)&data[offset] = (N)str.Size();
|
||||
Util::Copy(&data[offset], &str[0], str.Size(true));
|
||||
|
||||
offset += sizeof(N);
|
||||
|
||||
for (N i = 0; i < str.Size(); ++i)
|
||||
*(T*)&data[offset + i * sizeof(T)] = str[i];
|
||||
*(T*)&data[offset + str.Size(true)] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
N tmpSize = (N)str.Size();
|
||||
|
||||
for (N i = 0; i < sizeof(N); ++i)
|
||||
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
||||
|
||||
offset += sizeof(N);
|
||||
|
||||
for (N i = 0; i < str.Size(); ++i)
|
||||
for (N b = 0; b < sizeof(T); ++b)
|
||||
data[offset + i * sizeof(T) + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
||||
data[offset + sizeof(T) * i + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
||||
|
||||
*(T*)&data[offset + str.Size(true)] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (endianness == Endianness::LE)
|
||||
{
|
||||
N tmpSize = (N)str.Size();
|
||||
|
||||
for (N i = 0; i < sizeof(N); ++i)
|
||||
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
||||
|
||||
offset += sizeof(N);
|
||||
|
||||
for (N i = 0; i < str.Size(); ++i)
|
||||
for (N b = 0; b < sizeof(T); ++b)
|
||||
data[offset + i * sizeof(T) + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
||||
data[offset + sizeof(T) * i + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
||||
|
||||
*(T*)&data[offset + str.Size(true)] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(N*)&data[offset] = (N)str.Size();
|
||||
Util::Copy(&data[offset], &str[0], str.Size(true));
|
||||
|
||||
offset += sizeof(N);
|
||||
|
||||
for (N i = 0; i < str.Size(); ++i)
|
||||
*(T*)&data[offset + i * sizeof(T)] = str[i];
|
||||
*(T*)&data[offset + str.Size(true)] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
offset += str.Size() * sizeof(T);
|
||||
offset += inSize;
|
||||
}
|
||||
|
||||
void WriteVersion(const Version& value)
|
||||
@@ -477,8 +528,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -518,8 +568,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -559,8 +608,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -599,8 +647,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -640,8 +687,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -681,8 +727,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -721,8 +766,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -762,8 +806,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -803,8 +846,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -844,8 +886,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -885,8 +926,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -944,6 +984,26 @@ namespace ehs
|
||||
offset += ser.Size();
|
||||
}
|
||||
|
||||
void WritePadding(const N size)
|
||||
{
|
||||
if (size > this->size - offset)
|
||||
{
|
||||
N remainder = size - (this->size - offset);
|
||||
|
||||
Byte* r = new Byte[this->size + remainder];
|
||||
|
||||
Util::Copy(r, data, this->size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
this->size += remainder;
|
||||
}
|
||||
|
||||
Util::Zero(&data[offset], size);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Write(const T value)
|
||||
{
|
||||
@@ -953,8 +1013,7 @@ namespace ehs
|
||||
|
||||
Byte* r = new Byte[size + remainder];
|
||||
|
||||
for (N i = 0; i < size; ++i)
|
||||
r[i] = data[i];
|
||||
Util::Copy(r, data, size);
|
||||
|
||||
delete[] data;
|
||||
data = r;
|
||||
@@ -985,7 +1044,10 @@ namespace ehs
|
||||
void ReadArray(T* const value, O* const size)
|
||||
{
|
||||
if (!*size)
|
||||
*size = (O)Read<N>();
|
||||
{
|
||||
*size = (O)Read<N>();
|
||||
return;
|
||||
}
|
||||
|
||||
for (N i = 0; i < *size; ++i)
|
||||
value[i] = Read<T>();
|
||||
@@ -1013,13 +1075,40 @@ namespace ehs
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename O>
|
||||
Str<T, O> ReadStr(const O size = 0)
|
||||
template<typename T = Char_8, typename O = UInt_64>
|
||||
Str<T, O> ReadStr(O size = 0)
|
||||
{
|
||||
Str<T, O> result(size ? size : (O)Read<N>());
|
||||
bool sizeKnown = size;
|
||||
|
||||
for (O i = 0; i < result.Size(); ++i)
|
||||
result[i] = Read<T>();
|
||||
if (!sizeKnown)
|
||||
while (((T*)&data[offset])[size])
|
||||
++size;
|
||||
|
||||
Str<T, O> result(size);
|
||||
|
||||
if (CPU::GetEndianness() == Endianness::LE)
|
||||
{
|
||||
if (endianness == Endianness::LE)
|
||||
Util::Copy(&result[0], &data[offset], result.Size(true));
|
||||
else
|
||||
for (N i = 0; i < size; ++i)
|
||||
for (N b = 0; b < sizeof(T); ++b)
|
||||
((Byte*)&result[i])[b] = data[offset + sizeof(T) * i + b];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (endianness == Endianness::LE)
|
||||
for (N i = 0; i < size; ++i)
|
||||
for (N b = 0; b < sizeof(T); ++b)
|
||||
((Byte*)&result[i])[b] = data[offset + sizeof(T) * i + b];
|
||||
else
|
||||
Util::Copy(&result[0], &data[offset], result.Size(true));
|
||||
}
|
||||
|
||||
offset += result.Size(true);
|
||||
|
||||
if (!sizeKnown)
|
||||
offset++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -1795,23 +1795,23 @@ namespace ehs
|
||||
return result;
|
||||
}
|
||||
|
||||
/// A 32-bit FNV-1a hash algorithm.
|
||||
/// @param [in] str The string to hash.
|
||||
/// @returns The resulting hash. Zero if string does not contain any characters.
|
||||
static UInt_32 Hash_32(const Str<T, N>& str)
|
||||
{
|
||||
/// A 32-bit FNV-1a hash algorithm.
|
||||
/// @param [in] str The string to hash.
|
||||
/// @returns The resulting hash. Zero if string does not contain any characters.
|
||||
static UInt_32 Hash_32(const Str<T, N>& str)
|
||||
{
|
||||
if (!str.Size())
|
||||
return 0;
|
||||
|
||||
const Byte* const bytes = str.ToBytes();
|
||||
const Byte* const bytes = str.ToBytes();
|
||||
|
||||
UInt_32 hash = 2166136261ul;
|
||||
UInt_32 hash = 2166136261ul;
|
||||
|
||||
for (N i = 0; i < str.Size(true); ++i)
|
||||
hash = (hash ^ bytes[i]) * 16777619;
|
||||
for (N i = 0; i < str.Size(true); ++i)
|
||||
hash = (hash ^ bytes[i]) * 16777619;
|
||||
|
||||
return hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// A 32-bit FNV-1a hash algorithm.
|
||||
/// @returns The resulting hash. Zero if string does not contain any characters.
|
||||
@@ -1830,23 +1830,23 @@ namespace ehs
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// A 64-bit FNV-1a hash algorithm.
|
||||
/// @param [in] str The string to hash.
|
||||
/// A 64-bit FNV-1a hash algorithm.
|
||||
/// @param [in] str The string to hash.
|
||||
/// @returns The resulting hash. Zero if string does not contain any characters.
|
||||
static UInt_64 Hash_64(const Str<T, N>& str)
|
||||
{
|
||||
static UInt_64 Hash_64(const Str<T, N>& str)
|
||||
{
|
||||
if (!str.Size())
|
||||
return 0;
|
||||
|
||||
const Byte* const bytes = str.ToBytes();
|
||||
const Byte* const bytes = str.ToBytes();
|
||||
|
||||
UInt_64 hash = 14695981039346656037ull;
|
||||
UInt_64 hash = 14695981039346656037ull;
|
||||
|
||||
for (N i = 0; i < str.Size(true); ++i)
|
||||
hash = (hash ^ bytes[i]) * 1099511628211;
|
||||
for (N i = 0; i < str.Size(true); ++i)
|
||||
hash = (hash ^ bytes[i]) * 1099511628211;
|
||||
|
||||
return hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// A 64-bit FNV-1a hash algorithm.
|
||||
/// @returns The resulting hash. Zero if string does not contain any characters.
|
||||
@@ -1888,11 +1888,7 @@ namespace ehs
|
||||
if (aSize != bSize)
|
||||
return false;
|
||||
|
||||
for (UInt_64 i = 0; i < aSize; ++i)
|
||||
if (a[i] != b[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return Util::Compare(a, b, aSize);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/system/OS.h"
|
||||
#include "ehs/system/Architecture.h"
|
||||
|
||||
#define EHS_MAX_PATH 0x104
|
||||
#define EHS_UINT_8_MAX 0xFF
|
||||
@@ -25,6 +26,12 @@
|
||||
#define EHS_LDOUBLE_MAX 1.79769e+308
|
||||
#define EHS_LDOUBLE_MIN 2.22507e-308
|
||||
|
||||
#if defined(EHS_64_BIT)
|
||||
#define EHS_SIZE_MAX 0xFFFFFFFFFFFFFFFF
|
||||
#elif defined(EHS_32_BIT)
|
||||
#define EHS_SIZE_MAX 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#define EHS_INFINITE EHS_UINT_32_MAX
|
||||
|
||||
namespace ehs
|
||||
@@ -52,4 +59,12 @@ namespace ehs
|
||||
typedef signed long SInt_64;
|
||||
typedef long Int_64;
|
||||
#endif
|
||||
|
||||
#if defined(EHS_64_BIT)
|
||||
typedef UInt_64 Size;
|
||||
typedef SInt_64 SSize;
|
||||
#elif defined(EHS_32_BIT)
|
||||
typedef UInt_32 Size;
|
||||
typedef SInt_32 SSize;
|
||||
#endif
|
||||
}
|
@@ -229,7 +229,7 @@ namespace ehs
|
||||
case 1:
|
||||
return y;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,7 @@ namespace ehs
|
||||
case 1:
|
||||
return y;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
@@ -266,7 +266,7 @@ namespace ehs
|
||||
case 2:
|
||||
return z;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -282,7 +282,7 @@ namespace ehs
|
||||
case 2:
|
||||
return z;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 3.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
@@ -279,7 +279,7 @@ namespace ehs
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 4.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 4.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ namespace ehs
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
EHS_LOG_INT("Error", 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 4.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Index of, \"" + Str_8::FromNum(index) + "\" is out of range for a Vector 4.");
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/BaseObj.h"
|
||||
#include "ehs/Str.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
enum class DType : UInt_8
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class DVar : public BaseObj
|
||||
{
|
||||
private:
|
||||
Str_8 id;
|
||||
UInt_64 hashId;
|
||||
};
|
||||
}
|
56
include/ehs/db/Database.h
Normal file
56
include/ehs/db/Database.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Array.h"
|
||||
#include "DbTable.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Database
|
||||
{
|
||||
private:
|
||||
UInt_64 hashId;
|
||||
Str_8 id;
|
||||
Version version;
|
||||
Array<DbTable> tables;
|
||||
Str_8 dir;
|
||||
|
||||
public:
|
||||
Database();
|
||||
|
||||
Database(Str_8 id, const Version& version);
|
||||
|
||||
Database(Str_8 filePath);
|
||||
|
||||
Database(Database&& db) noexcept;
|
||||
|
||||
Database(const Database& db);
|
||||
|
||||
Database& operator=(Database&& db) noexcept;
|
||||
|
||||
Database& operator=(const Database& db);
|
||||
|
||||
UInt_64 GetHashId() const;
|
||||
|
||||
void SetId(Str_8 newId);
|
||||
|
||||
Str_8 GetId() const;
|
||||
|
||||
void SetVersion(const Version& newVersion);
|
||||
|
||||
Version GetVersion() const;
|
||||
|
||||
bool HasTable(UInt_64 hashId) const;
|
||||
|
||||
bool HasTable(const Str_8& id) const;
|
||||
|
||||
DbTable* CreateTable(Str_8 id);
|
||||
|
||||
DbTable* GetTable(UInt_64 hashId) const;
|
||||
|
||||
DbTable* GetTable(const Str_8& id) const;
|
||||
|
||||
Str_8 GetDirectory() const;
|
||||
|
||||
void Save(Str_8 directory);
|
||||
};
|
||||
}
|
52
include/ehs/db/DbObject.h
Normal file
52
include/ehs/db/DbObject.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Array.h"
|
||||
#include "DbVar.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class DbTable;
|
||||
|
||||
class DbObject
|
||||
{
|
||||
private:
|
||||
friend class DbTable;
|
||||
friend class DbVar;
|
||||
|
||||
UInt_64 id;
|
||||
DbTable* parent;
|
||||
Array<DbVar> vars;
|
||||
|
||||
public:
|
||||
DbObject();
|
||||
|
||||
DbObject(UInt_64 id);
|
||||
|
||||
DbObject(DbObject&& obj) noexcept;
|
||||
|
||||
DbObject(const DbObject& obj);
|
||||
|
||||
DbObject& operator=(DbObject&& obj) noexcept;
|
||||
|
||||
DbObject& operator=(const DbObject& obj);
|
||||
|
||||
UInt_64 GetId() const;
|
||||
|
||||
bool HasVariable(UInt_64 hashId) const;
|
||||
|
||||
DbVar* GetVariable(UInt_64 hashId) const;
|
||||
|
||||
DbVar* GetVariable(const Str_8& id) const;
|
||||
|
||||
void Save() const;
|
||||
|
||||
void Load();
|
||||
|
||||
bool IsLoaded() const;
|
||||
|
||||
void Free();
|
||||
|
||||
private:
|
||||
void CreateVariable(DbVarTmpl* master);
|
||||
};
|
||||
}
|
66
include/ehs/db/DbTable.h
Normal file
66
include/ehs/db/DbTable.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Version.h"
|
||||
#include "ehs/Array.h"
|
||||
#include "DbVarTmpl.h"
|
||||
#include "DbObject.h"
|
||||
#include "ehs/Serializer.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Database;
|
||||
|
||||
class DbTable
|
||||
{
|
||||
private:
|
||||
friend class Database;
|
||||
friend class DbVar;
|
||||
friend class DbObject;
|
||||
|
||||
Database *parent;
|
||||
UInt_64 hashId;
|
||||
Str_8 id;
|
||||
Array<DbVarTmpl> varTmpls;
|
||||
Array<DbObject> objects;
|
||||
|
||||
public:
|
||||
DbTable();
|
||||
|
||||
DbTable(Str_8 id);
|
||||
|
||||
DbTable(DbTable&& table) noexcept;
|
||||
|
||||
DbTable(const DbTable& table);
|
||||
|
||||
DbTable& operator=(DbTable&& table) noexcept;
|
||||
|
||||
DbTable& operator=(const DbTable& table);
|
||||
|
||||
UInt_64 GetHashId() const;
|
||||
|
||||
void SetId(Str_8 newId);
|
||||
|
||||
Str_8 GetId() const;
|
||||
|
||||
bool HasVariable(UInt_64 hashId) const;
|
||||
|
||||
bool HasVariable(const Str_8& id) const;
|
||||
|
||||
bool CreateVariable(DbVarTmpl var);
|
||||
|
||||
DbObject *CreateObject();
|
||||
|
||||
DbObject *GetObject(UInt_64 variableHashId, const Str_8 &value) const;
|
||||
|
||||
DbObject *GetObject(const Str_8 &variable, const Str_8 &value) const;
|
||||
|
||||
DbObject *GetObject(UInt_64 id) const;
|
||||
|
||||
private:
|
||||
DbVarTmpl *GetVariableTemplate(UInt_64 hashId) const;
|
||||
|
||||
void Serialize(const Str_8 &dir, Serializer<UInt_64>& data) const;
|
||||
|
||||
void Deserialize(const Str_8 &dir, Serializer<UInt_64>& data);
|
||||
};
|
||||
}
|
105
include/ehs/db/DbVar.h
Normal file
105
include/ehs/db/DbVar.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Types.h"
|
||||
#include "ehs/Serializer.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class DbVarTmpl;
|
||||
class DbObject;
|
||||
|
||||
class DbVar
|
||||
{
|
||||
private:
|
||||
friend class DbObject;
|
||||
|
||||
UInt_64 hashId;
|
||||
DbObject *parent;
|
||||
Byte *value;
|
||||
UInt_64 size;
|
||||
|
||||
public:
|
||||
~DbVar();
|
||||
|
||||
DbVar();
|
||||
|
||||
DbVar(UInt_64 hashId, const DbVarTmpl *master);
|
||||
|
||||
DbVar(DbVar &&var) noexcept;
|
||||
|
||||
DbVar(const DbVar &var);
|
||||
|
||||
DbVar &operator=(DbVar &&var) noexcept;
|
||||
|
||||
DbVar &operator=(const DbVar &var);
|
||||
|
||||
explicit operator Byte *() const;
|
||||
|
||||
UInt_64 GetHashId() const;
|
||||
|
||||
template<typename T>
|
||||
void SetValueArray(const T* const newValue, const UInt_64 newSize)
|
||||
{
|
||||
size = sizeof(T) * newSize;
|
||||
|
||||
value = new Byte[size];
|
||||
|
||||
Util::Copy(value, newValue, size);
|
||||
}
|
||||
|
||||
template<typename T = Char_8>
|
||||
void SetValueStr(const T * const newValue)
|
||||
{
|
||||
size = sizeof(T) * Str<Char_8, UInt_64>::Len(newValue);
|
||||
|
||||
value = new Byte[size];
|
||||
|
||||
Util::Copy(value, newValue, size);
|
||||
}
|
||||
|
||||
template<typename T = Char_8, typename I = UInt_64>
|
||||
void SetValueStr(const Str<T, I>& newValue)
|
||||
{
|
||||
size = newValue.Size(true);
|
||||
|
||||
value = new Byte[size];
|
||||
|
||||
Util::Copy(value, &newValue[0], size);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SetValue(const Byte* newValue)
|
||||
{
|
||||
size = sizeof(T);
|
||||
|
||||
value = new Byte[size];
|
||||
|
||||
Util::Copy(value, newValue, size);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* GetValueArray() const
|
||||
{
|
||||
return (T*)value;
|
||||
}
|
||||
|
||||
template<typename T = Char_8, typename I = UInt_64>
|
||||
Str<T, I> GetValueStr() const
|
||||
{
|
||||
return {(T*)value, size / sizeof(T)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T GetValue() const
|
||||
{
|
||||
return *(T*)value;
|
||||
}
|
||||
|
||||
UInt_64 GetSize() const;
|
||||
|
||||
private:
|
||||
void Serialize(Serializer<UInt_64> &data) const;
|
||||
|
||||
void Deserialize(Serializer<UInt_64> &data);
|
||||
};
|
||||
}
|
77
include/ehs/db/DbVarTmpl.h
Normal file
77
include/ehs/db/DbVarTmpl.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Serializer.h"
|
||||
#include "ehs/Str.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class DbVar;
|
||||
|
||||
class DbVarTmpl
|
||||
{
|
||||
private:
|
||||
friend class DbTable;
|
||||
|
||||
UInt_64 hashId;
|
||||
Str_8 id;
|
||||
Byte* def;
|
||||
UInt_64 size;
|
||||
|
||||
public:
|
||||
~DbVarTmpl();
|
||||
|
||||
DbVarTmpl();
|
||||
|
||||
template<typename T>
|
||||
DbVarTmpl(Str_8 id, const T* const def, UInt_64 size)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), def(new Byte[sizeof(T) * size]), size(sizeof(T) * size)
|
||||
{
|
||||
Util::Copy(this->def, def, this->size);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
DbVarTmpl(Str_8 id, const T* const def)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), def(new Byte[sizeof(T)]), size(sizeof(T))
|
||||
{
|
||||
Util::Copy(this->def, def, this->size);
|
||||
}
|
||||
|
||||
DbVarTmpl(Str_8 id);
|
||||
|
||||
DbVarTmpl(DbVarTmpl&& varTmpl) noexcept;
|
||||
|
||||
DbVarTmpl(const DbVarTmpl& varTmpl);
|
||||
|
||||
DbVarTmpl& operator=(DbVarTmpl&& varTmpl) noexcept;
|
||||
|
||||
DbVarTmpl& operator=(const DbVarTmpl& varTmpl);
|
||||
|
||||
operator Byte *() const;
|
||||
|
||||
UInt_64 GetHashId() const;
|
||||
|
||||
void SetId(Str_8 newId);
|
||||
|
||||
Str_8 GetId() const;
|
||||
|
||||
template<typename T>
|
||||
T* GetDefaultArray() const
|
||||
{
|
||||
return (T*)def;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T GetDefault() const
|
||||
{
|
||||
return *(T*)def;
|
||||
}
|
||||
|
||||
UInt_64 GetSize() const;
|
||||
|
||||
private:
|
||||
void Serialize(Serializer<UInt_64> &data) const;
|
||||
|
||||
void Deserialize(Serializer<UInt_64> &data);
|
||||
};
|
||||
}
|
17
include/ehs/io/BaseDirectory.h
Normal file
17
include/ehs/io/BaseDirectory.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Array.h"
|
||||
#include "ehs/Str.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class BaseDirectory
|
||||
{
|
||||
public:
|
||||
static Array<Str_8> GetAllFiles(const Str_8 &dir);
|
||||
|
||||
static void CreateRecursive(Str_8 dir);
|
||||
|
||||
static void Create(const Str_8 &dir);
|
||||
};
|
||||
}
|
@@ -1,9 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Str.h"
|
||||
#include "ehs/Vec2.h"
|
||||
#include "ehs/Rect.h"
|
||||
#include "ehs/io/hid/Input.h"
|
||||
|
||||
namespace ehs
|
||||
@@ -60,10 +58,6 @@ namespace ehs
|
||||
|
||||
bool HasFocus() const;
|
||||
|
||||
void EnableResizing(bool enable);
|
||||
|
||||
bool IsResizable() const;
|
||||
|
||||
/// Gets the cursors position on the desktop in pixels.
|
||||
/// @param [in] relative Whether the position should be relative to the windows client.
|
||||
/// @returns The current value.
|
||||
|
9
include/ehs/io/Directory.h
Normal file
9
include/ehs/io/Directory.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/system/OS.h"
|
||||
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
#include "Directory_W32.h"
|
||||
#elif defined(EHS_OS_LINUX)
|
||||
#include "Directory_LNX.h"
|
||||
#endif
|
16
include/ehs/io/Directory_LNX.h
Normal file
16
include/ehs/io/Directory_LNX.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseDirectory.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Directory : public BaseDirectory
|
||||
{
|
||||
public:
|
||||
static Array<Str_8> GetAllFiles(const Str_8 &dir);
|
||||
|
||||
static void CreateRecursive(Str_8 dir);
|
||||
|
||||
static void Create(const Str_8 &dir);
|
||||
};
|
||||
}
|
16
include/ehs/io/Directory_W32.h
Normal file
16
include/ehs/io/Directory_W32.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseDirectory.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Directory : public BaseDirectory
|
||||
{
|
||||
public:
|
||||
static Array<Str_8> GetAllFiles(const Str_8 &dir);
|
||||
|
||||
static void CreateRecursive(Str_8 dir);
|
||||
|
||||
static void Create(const Str_8 &dir);
|
||||
};
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/system/OS.h"
|
||||
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
#include "File_W32.h"
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include "Glyph.h"
|
||||
#include "ehs/Anchor.h"
|
||||
#include "ehs/io/img/Img.h"
|
||||
#include "ehs/io/model/Mesh.h"
|
||||
#include "ehs/io/mdl/Mesh.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
|
@@ -20,7 +20,7 @@ namespace ehs
|
||||
public:
|
||||
Glyph();
|
||||
|
||||
Glyph(Serializer<>& ser);
|
||||
Glyph(Serializer<UInt_64>& ser);
|
||||
|
||||
Glyph(const Char_32 code);
|
||||
|
||||
|
48
include/ehs/io/UsbBase.h
Normal file
48
include/ehs/io/UsbBase.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Types.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class UsbBase
|
||||
{
|
||||
private:
|
||||
UInt_32 bus;
|
||||
UInt_32 address;
|
||||
|
||||
public:
|
||||
virtual ~UsbBase() = default;
|
||||
|
||||
UsbBase();
|
||||
|
||||
UsbBase(UInt_32 bus, UInt_32 address);
|
||||
|
||||
UsbBase(UsbBase&& usb) noexcept;
|
||||
|
||||
UsbBase(const UsbBase& usb);
|
||||
|
||||
UsbBase& operator=(UsbBase&& usb) noexcept;
|
||||
|
||||
UsbBase& operator=(const UsbBase& usb);
|
||||
|
||||
virtual void Initialize() = 0;
|
||||
|
||||
virtual void Release() = 0;
|
||||
|
||||
virtual bool IsInitialized() const = 0;
|
||||
|
||||
virtual Size Send(const Byte* data, Size size) = 0;
|
||||
|
||||
void BulkSend(const Byte* data, Size size);
|
||||
|
||||
virtual Size Receive(Byte* data, Size size) = 0;
|
||||
|
||||
void BulkReceive(Byte** data, Size* size);
|
||||
|
||||
UInt_32 GetBus() const;
|
||||
|
||||
UInt_32 GetAddress() const;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
}
|
34
include/ehs/io/Usb_LNX.h
Normal file
34
include/ehs/io/Usb_LNX.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "UsbBase.h"
|
||||
#include "File.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Usb final : public UsbBase
|
||||
{
|
||||
private:
|
||||
int hdl;
|
||||
|
||||
public:
|
||||
~Usb() override;
|
||||
|
||||
Usb();
|
||||
|
||||
Usb(UInt_32 bus, UInt_32 address);
|
||||
|
||||
Usb(Usb&& usb) noexcept;
|
||||
|
||||
Usb(const Usb& usb);
|
||||
|
||||
Usb& operator=(Usb&& usb) noexcept;
|
||||
|
||||
Usb& operator=(const Usb& usb);
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void Release() override;
|
||||
|
||||
bool IsInitialized() const override;
|
||||
};
|
||||
}
|
@@ -4,21 +4,27 @@
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include "xdg-decoration.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Window : public BaseWindow
|
||||
{
|
||||
private:
|
||||
wl_display* display;
|
||||
protected:
|
||||
wl_display *display;
|
||||
wl_registry *registry;
|
||||
wl_compositor* compositor;
|
||||
wl_surface* surface;
|
||||
wl_compositor *compositor;
|
||||
wl_surface *wlSurface;
|
||||
xdg_wm_base *xdgShell;
|
||||
xdg_surface *xdgSurface;
|
||||
xdg_toplevel *xdgToplevel;
|
||||
zxdg_decoration_manager_v1 *decManager;
|
||||
zxdg_toplevel_decoration_v1 *dec;
|
||||
wl_seat *seat;
|
||||
wl_pointer *pointer;
|
||||
Vec2_u32 scale;
|
||||
|
||||
static void SurfaceConfigure(void *data, xdg_surface *xdg_surface, UInt_32 serial);
|
||||
static void SurfaceConfigEvent(void *data, xdg_surface *xdg_surface, UInt_32 serial);
|
||||
|
||||
static void ShellPing(void *data, xdg_wm_base *shell, UInt_32 serial);
|
||||
|
||||
@@ -26,16 +32,32 @@ namespace ehs
|
||||
|
||||
static void RegistryRemoved(void *data, wl_registry *registry, UInt_32 id);
|
||||
|
||||
static void ResizeEvent(void *data, xdg_toplevel *xdg_toplevel, Int_32 width, Int_32 height, wl_array *states);
|
||||
|
||||
static void CloseEvent(void *data, xdg_toplevel *xdg_toplevel);
|
||||
|
||||
static void SeatCapabilitiesEvent(void *data, wl_seat *seat, UInt_32 capabilities);
|
||||
|
||||
static void PointerMotionEvent(void *data, wl_pointer *pointer, UInt_32 time, wl_fixed_t sx, wl_fixed_t sy);
|
||||
|
||||
public:
|
||||
~Window() override;
|
||||
|
||||
Window();
|
||||
|
||||
void Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
||||
Window(Window &&win) noexcept;
|
||||
|
||||
void Create_16(const Str_16& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
||||
Window(const Window &win);
|
||||
|
||||
void Create_8(const Str_8& title, const Vec2_s32& pos, const Vec2_u32 scale) override;
|
||||
Window &operator=(Window &&win) noexcept;
|
||||
|
||||
Window &operator=(const Window &win);
|
||||
|
||||
void Create_32(const Str_32& title, const Vec2_s32& pos, Vec2_u32 scale) override;
|
||||
|
||||
void Create_16(const Str_16& title, const Vec2_s32& pos, Vec2_u32 scale) override;
|
||||
|
||||
void Create_8(const Str_8& title, const Vec2_s32& pos, Vec2_u32 scale) override;
|
||||
|
||||
void OnCreated() override;
|
||||
|
||||
|
@@ -39,7 +39,9 @@ namespace ehs
|
||||
|
||||
Audio();
|
||||
|
||||
Audio(Str_8 id);
|
||||
Audio(const Str_8& filePath);
|
||||
|
||||
Audio(const Str_8& filePath, DataType type);
|
||||
|
||||
Audio(Str_8 id, UInt_64 sampleRate, DataType dataType, UInt_8 channels, UInt_64 frames, const Byte* data);
|
||||
|
||||
@@ -123,17 +125,7 @@ namespace ehs
|
||||
|
||||
Audio GetAsChannels(UInt_8 newChannels) const;
|
||||
|
||||
bool ToFile(const Str_8& filePath) const;
|
||||
|
||||
static Audio FromFile(const Str_8& filePath);
|
||||
|
||||
static Audio* FromFile_Heap(const Str_8& filePath);
|
||||
|
||||
static Audio FromFile(const Str_8& filePath, DataType required);
|
||||
|
||||
static Audio* FromFile_Heap(const Str_8& filePath, DataType required);
|
||||
|
||||
static Audio FromData(Str_8 id, const Str_8& ext, Serializer<UInt_64>& data);
|
||||
bool Export(const Str_8& filePath) const;
|
||||
|
||||
private:
|
||||
void ToMono(UInt_64 newFrameCount, Byte* newData, UInt_64 frameOffset) const;
|
||||
@@ -201,4 +193,10 @@ namespace ehs
|
||||
|
||||
void SInt_32_to_SInt_64(Byte* newData, Byte* newPeak) const;
|
||||
};
|
||||
|
||||
bool EncodeEHA(const ehs::AudioCodec* codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Audio* in);
|
||||
|
||||
bool DecodeEHA(const ehs::AudioCodec* codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Audio* out);
|
||||
|
||||
bool DecodeWAV(const ehs::AudioCodec* codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Audio* out);
|
||||
}
|
@@ -42,7 +42,7 @@ namespace ehs
|
||||
|
||||
Img();
|
||||
|
||||
Img(Str_8 id);
|
||||
Img(const Str_8& filePath);
|
||||
|
||||
Img(Str_8 id, UInt_8 byteDepth, UInt_8 channels, const Vec2_u64& resolution, const Byte* data);
|
||||
|
||||
@@ -124,13 +124,7 @@ namespace ehs
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
bool ToFile(const Str_8& filePath) const;
|
||||
|
||||
static Img FromFile(const Str_8& filePath);
|
||||
|
||||
static Img* FromFile_Heap(const Str_8& filePath);
|
||||
|
||||
static Img FromData(Str_8 id, const Str_8& ext, Serializer<UInt_64>& data);
|
||||
bool Export(const Str_8& filePath) const;
|
||||
|
||||
private:
|
||||
Img GetNearestNeighbor(const Vec2_u64& newResolution) const;
|
||||
@@ -185,4 +179,10 @@ namespace ehs
|
||||
|
||||
void BD16_to_BD8(UInt_64 newSize, Byte* buffer) const;
|
||||
};
|
||||
|
||||
bool EncodeQOI(const ehs::ImgCodec* codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Img* in);
|
||||
|
||||
bool DecodeQOI(const ehs::ImgCodec* codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Img* out);
|
||||
|
||||
bool DecodePNG(const ehs::ImgCodec* codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Img* out);
|
||||
}
|
||||
|
@@ -7,6 +7,10 @@
|
||||
namespace ehs
|
||||
{
|
||||
class Img;
|
||||
class ImgCodec;
|
||||
|
||||
typedef bool (*EncodeImgCb)(const ImgCodec* const, Serializer<UInt_64>&, const Img*);
|
||||
typedef bool (*DecodeImgCb)(const ImgCodec* const, Serializer<UInt_64>&, Img*);
|
||||
|
||||
class ImgCodec
|
||||
{
|
||||
@@ -15,15 +19,13 @@ namespace ehs
|
||||
UInt_64 hashExt;
|
||||
Str_8 ext;
|
||||
Endianness endianness;
|
||||
bool (*encodeCb)(const ImgCodec* const, Serializer<UInt_64>&, const Img*);
|
||||
bool (*decodeCb)(const ImgCodec* const, Serializer<UInt_64>&, Img*);
|
||||
EncodeImgCb encoder;
|
||||
DecodeImgCb decoder;
|
||||
|
||||
public:
|
||||
ImgCodec();
|
||||
|
||||
ImgCodec(Str_8 id, Str_8 ext, const Endianness end,
|
||||
bool (*encodeCb)(const ImgCodec* const, Serializer<UInt_64>&, const Img*),
|
||||
bool (*decodeCb)(const ImgCodec* const, Serializer<UInt_64>&, Img*));
|
||||
ImgCodec(Str_8 id, Str_8 ext, Endianness end, EncodeImgCb encoder, DecodeImgCb decoder);
|
||||
|
||||
ImgCodec(ImgCodec&& codec) noexcept;
|
||||
|
||||
|
93
include/ehs/io/mdl/Mdl.h
Normal file
93
include/ehs/io/mdl/Mdl.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Array.h"
|
||||
#include "ehs/io/File.h"
|
||||
#include "MdlCodec.h"
|
||||
#include "Mesh.h"
|
||||
#include "Bone.h"
|
||||
#include "Animation.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
enum class ModelEncoding : UInt_8
|
||||
{
|
||||
EHM
|
||||
};
|
||||
|
||||
class Mdl : public BaseObj
|
||||
{
|
||||
private:
|
||||
static Array<MdlCodec> codecs;
|
||||
|
||||
protected:
|
||||
UInt_64 hashId;
|
||||
Str_8 id;
|
||||
Array<Mesh> meshes;
|
||||
Bone skeleton;
|
||||
Array<Animation> animations;
|
||||
|
||||
public:
|
||||
static bool HasCodec(UInt_64 hashExt);
|
||||
|
||||
static bool HasCodec(const Str_8& ext);
|
||||
|
||||
static bool AddCodec(MdlCodec codec);
|
||||
|
||||
static const MdlCodec* GetCodec(UInt_64 hashExt);
|
||||
|
||||
static const MdlCodec* GetCodec(const Str_8& ext);
|
||||
|
||||
Mdl();
|
||||
|
||||
Mdl(const Str_8& filePath);
|
||||
|
||||
Mdl(Str_8 id, Array<Mesh> meshes, Bone skeleton, Array<Animation> animations);
|
||||
|
||||
Mdl(Str_8 id, Array<Mesh> meshes, Bone skeleton);
|
||||
|
||||
Mdl(Str_8 id, Array<Mesh> meshes);
|
||||
|
||||
Mdl(Mdl&& model) noexcept;
|
||||
|
||||
Mdl(const Mdl& model) = default;
|
||||
|
||||
Mdl& operator=(Mdl&& model) noexcept;
|
||||
|
||||
Mdl& operator=(const Mdl& model) = default;
|
||||
|
||||
void Release();
|
||||
|
||||
UInt_64 GetHashId() const;
|
||||
|
||||
void SetId(Str_8 newId);
|
||||
|
||||
Str_8 GetId() const;
|
||||
|
||||
const Array<Mesh>& GetMeshes() const;
|
||||
|
||||
Array<Mesh>& GetMeshes();
|
||||
|
||||
Mesh* GetMesh(UInt_64 inHashId);
|
||||
|
||||
Mesh* GetMesh(const Str_8& inId);
|
||||
|
||||
const Bone& GetSkeleton() const;
|
||||
|
||||
Bone& GetSkeleton();
|
||||
|
||||
Animation* GetAnimation(UInt_64 inHashId);
|
||||
|
||||
const Array<Animation>& GetAnimations() const;
|
||||
|
||||
Array<Animation>& GetAnimations();
|
||||
|
||||
void Calculate();
|
||||
|
||||
bool Export(const Str_8& filePath) const;
|
||||
};
|
||||
|
||||
bool EncodeEHM(const MdlCodec* codec, Serializer<UInt_64>& data, const Mdl* mdl);
|
||||
|
||||
bool DecodeEHM(const MdlCodec* codec, Serializer<UInt_64>& data, Mdl* mdl);
|
||||
}
|
50
include/ehs/io/mdl/MdlCodec.h
Normal file
50
include/ehs/io/mdl/MdlCodec.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/Str.h"
|
||||
#include "ehs/Serializer.h"
|
||||
#include "ehs/system/CPU.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class Mdl;
|
||||
class MdlCodec;
|
||||
|
||||
typedef bool (*EnocdeMdlCb)(const MdlCodec*, Serializer<UInt_64>&, const Mdl*);
|
||||
typedef bool (*DecodeMdlCb)(const MdlCodec*, Serializer<UInt_64>&, Mdl*);
|
||||
|
||||
class MdlCodec
|
||||
{
|
||||
private:
|
||||
Str_8 id;
|
||||
UInt_64 hashExt;
|
||||
Str_8 ext;
|
||||
Endianness endianness;
|
||||
EnocdeMdlCb encoder;
|
||||
DecodeMdlCb decoder;
|
||||
|
||||
public:
|
||||
MdlCodec();
|
||||
|
||||
MdlCodec(Str_8 id, Str_8 ext, Endianness end, EnocdeMdlCb encoder, DecodeMdlCb decoder);
|
||||
|
||||
MdlCodec(MdlCodec&& codec) noexcept;
|
||||
|
||||
MdlCodec(const MdlCodec& codec);
|
||||
|
||||
MdlCodec& operator=(MdlCodec&& codec) noexcept;
|
||||
|
||||
MdlCodec& operator=(const MdlCodec& codec);
|
||||
|
||||
Str_8 GetId() const;
|
||||
|
||||
UInt_64 GetHashExt() const;
|
||||
|
||||
Str_8 GetExt() const;
|
||||
|
||||
Endianness GetEndianness() const;
|
||||
|
||||
bool Encode(Serializer<UInt_64>& out, const Mdl* in) const;
|
||||
|
||||
bool Decode(Serializer<UInt_64>& in, Mdl* out) const;
|
||||
};
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Array.h"
|
||||
#include "ehs/io/File.h"
|
||||
#include "Mesh.h"
|
||||
#include "Bone.h"
|
||||
#include "Animation.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
enum class ModelEncoding : UInt_8
|
||||
{
|
||||
EHM
|
||||
};
|
||||
|
||||
class Model : public BaseObj
|
||||
{
|
||||
protected:
|
||||
UInt_64 hashId;
|
||||
Str_8 id;
|
||||
Array<Mesh> meshes;
|
||||
Bone skeleton;
|
||||
Array<Animation> animations;
|
||||
|
||||
public:
|
||||
Model();
|
||||
|
||||
Model(const Str_8& filePath);
|
||||
|
||||
Model(Str_8 id, Array<Mesh> meshes, Bone skeleton, Array<Animation> animations);
|
||||
|
||||
Model(Str_8 id, Array<Mesh> meshes, Bone skeleton);
|
||||
|
||||
Model(Str_8 id, Array<Mesh> meshes);
|
||||
|
||||
Model(Model&& model) noexcept;
|
||||
|
||||
Model(const Model& model) = default;
|
||||
|
||||
Model& operator=(Model&& model) noexcept;
|
||||
|
||||
Model& operator=(const Model& model) = default;
|
||||
|
||||
void Release();
|
||||
|
||||
UInt_64 GetHashId() const;
|
||||
|
||||
void SetId(Str_8 newId);
|
||||
|
||||
Str_8 GetId() const;
|
||||
|
||||
const Array<Mesh>& GetMeshes() const;
|
||||
|
||||
Array<Mesh>& GetMeshes();
|
||||
|
||||
Mesh* GetMesh(UInt_64 inHashId);
|
||||
|
||||
Mesh* GetMesh(const Str_8& inId);
|
||||
|
||||
const Bone& GetSkeleton() const;
|
||||
|
||||
Bone& GetSkeleton();
|
||||
|
||||
Animation* GetAnimation(UInt_64 inHashId);
|
||||
|
||||
const Array<Animation>& GetAnimations() const;
|
||||
|
||||
Array<Animation>& GetAnimations();
|
||||
|
||||
void Calculate();
|
||||
|
||||
void Export(const Str_8& filePath, ModelEncoding encoding);
|
||||
|
||||
private:
|
||||
void ToEHM(File& file);
|
||||
|
||||
void FromEHM(File& file);
|
||||
};
|
||||
}
|
18
include/ehs/io/socket/BaseDNS.h
Normal file
18
include/ehs/io/socket/BaseDNS.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Socket.h"
|
||||
#include "ehs/Str.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class BaseDNS
|
||||
{
|
||||
public:
|
||||
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
|
||||
|
||||
/// Resolves a hostname to an ip address.
|
||||
/// @param [in] hostname The given hostname to resolve.
|
||||
/// @returns The resulting ip address.
|
||||
static Str_8 Resolve(const Str_8 &hostname);
|
||||
};
|
||||
}
|
@@ -146,6 +146,10 @@ namespace ehs
|
||||
/// @returns The result.
|
||||
virtual bool IsBlocking() const = 0;
|
||||
|
||||
virtual void SetIPv6Only(bool value) = 0;
|
||||
|
||||
virtual bool IsIPv6Only() const = 0;
|
||||
|
||||
/// Retrieves whether or not this socket was initialized.
|
||||
/// @returns The result.
|
||||
virtual bool IsValid() const = 0;
|
||||
|
@@ -69,6 +69,10 @@ namespace ehs
|
||||
/// @returns The result.
|
||||
virtual bool IsBlocking() const = 0;
|
||||
|
||||
virtual void SetIPv6Only(bool value) = 0;
|
||||
|
||||
virtual bool IsIPv6Only() const = 0;
|
||||
|
||||
/// Retrieves the bound ip version.
|
||||
/// @returns The result.
|
||||
AddrType GetLocalAddressType() const;
|
||||
|
@@ -1,17 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Str.h"
|
||||
#include "Socket.h"
|
||||
#include "ehs/system/OS.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class DNS
|
||||
{
|
||||
public:
|
||||
/// Resolves a hostname to an ip address.
|
||||
/// @param [in] hostname The given hostname to resolve.
|
||||
/// @returns The resulting ip address.
|
||||
static Str_8 Resolve(const Str_8& hostname);
|
||||
};
|
||||
}
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
#include "DNS_W32.h"
|
||||
#elif defined(EHS_OS_LINUX)
|
||||
#include "DNS_LNX.h"
|
||||
#endif
|
17
include/ehs/io/socket/DNS_LNX.h
Normal file
17
include/ehs/io/socket/DNS_LNX.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseDNS.h"
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Str.h"
|
||||
#include "Socket.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class DNS final : public BaseDNS
|
||||
{
|
||||
public:
|
||||
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
|
||||
|
||||
static Str_8 Resolve(const Str_8 &hostname);
|
||||
};
|
||||
}
|
14
include/ehs/io/socket/DNS_W32.h
Normal file
14
include/ehs/io/socket/DNS_W32.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseDNS.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
class DNS final : public BaseDNS
|
||||
{
|
||||
public:
|
||||
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
|
||||
|
||||
static Str_8 Resolve(const Str_8 &hostname);
|
||||
};
|
||||
}
|
@@ -80,6 +80,10 @@ namespace ehs
|
||||
/// @returns The result.
|
||||
bool IsBlocking() const override;
|
||||
|
||||
void SetIPv6Only(bool value) override;
|
||||
|
||||
bool IsIPv6Only() const override;
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
private:
|
||||
|
@@ -80,6 +80,10 @@ namespace ehs
|
||||
/// @returns The result.
|
||||
bool IsBlocking() const override;
|
||||
|
||||
void SetIPv6Only(bool value) override;
|
||||
|
||||
bool IsIPv6Only() const override;
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
private:
|
||||
|
@@ -68,6 +68,10 @@ namespace ehs
|
||||
/// @returns The result.
|
||||
bool IsBlocking() const override;
|
||||
|
||||
void SetIPv6Only(bool value) override;
|
||||
|
||||
bool IsIPv6Only() const override;
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
private:
|
||||
|
@@ -68,6 +68,10 @@ namespace ehs
|
||||
/// @returns The result.
|
||||
bool IsBlocking() const override;
|
||||
|
||||
void SetIPv6Only(bool value) override;
|
||||
|
||||
bool IsIPv6Only() const override;
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
private:
|
||||
|
@@ -21,7 +21,7 @@ namespace ehs
|
||||
Str_8 id;
|
||||
};
|
||||
|
||||
class Spotify
|
||||
class Spotify final
|
||||
{
|
||||
private:
|
||||
SSL client;
|
||||
@@ -40,14 +40,14 @@ namespace ehs
|
||||
|
||||
Spotify();
|
||||
|
||||
Spotify(const Str_8& clientId, const Str_8& secret, const Str_8& redURI, const Array<Str_8>& scopes, const bool forceVerify);
|
||||
Spotify(Str_8 clientId, Str_8 secret, Str_8 redURI, Array<Str_8> scopes, bool forceVerify);
|
||||
|
||||
bool Authorize();
|
||||
|
||||
/// Sets the volume for a device.
|
||||
/// @param [in] level The percentage to set the volume to.
|
||||
/// @returns The response code.
|
||||
UInt_32 SetVolume(const UInt_8 level);
|
||||
UInt_32 SetVolume(UInt_8 level);
|
||||
|
||||
/// Resume playback for a device.
|
||||
/// @returns The response code.
|
||||
@@ -60,12 +60,12 @@ namespace ehs
|
||||
/// Repeats playback for a device.
|
||||
/// @param [in] status The status to set it to.
|
||||
/// @returns The response code.
|
||||
UInt_32 SetRepeat(const SpotifyState state);
|
||||
UInt_32 SetRepeat(SpotifyState state);
|
||||
|
||||
/// Shuffles playback for a device.
|
||||
/// @param [in] state The state to set shuffle to.
|
||||
/// @returns The response code.
|
||||
UInt_32 SetShuffle(const bool state);
|
||||
UInt_32 SetShuffle(bool state);
|
||||
|
||||
UInt_32 SearchTrack(Vector<Str_8>& artists, Str_8& id, Str_8& name);
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace ehs
|
||||
/// Seeks to a position of the currently playing track in milliseconds.
|
||||
/// @param [in] pos The position in milliseconds to seek to.
|
||||
/// @returns The response code.
|
||||
UInt_32 Seek(const UInt_32 pos);
|
||||
UInt_32 Seek(UInt_32 pos);
|
||||
|
||||
Str_8 GetClientId() const;
|
||||
|
||||
|
377
include/ehs/io/xdg-decoration.h
Normal file
377
include/ehs/io/xdg-decoration.h
Normal file
@@ -0,0 +1,377 @@
|
||||
/* Generated by wayland-scanner 1.23.0 */
|
||||
|
||||
#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol
|
||||
* @section page_ifaces_xdg_decoration_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager
|
||||
* - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface
|
||||
* @section page_copyright_xdg_decoration_unstable_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* Copyright © 2018 Simon Ser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
* </pre>
|
||||
*/
|
||||
struct xdg_toplevel;
|
||||
struct zxdg_decoration_manager_v1;
|
||||
struct zxdg_toplevel_decoration_v1;
|
||||
|
||||
#ifndef ZXDG_DECORATION_MANAGER_V1_INTERFACE
|
||||
#define ZXDG_DECORATION_MANAGER_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1
|
||||
* @section page_iface_zxdg_decoration_manager_v1_desc Description
|
||||
*
|
||||
* This interface allows a compositor to announce support for server-side
|
||||
* decorations.
|
||||
*
|
||||
* A window decoration is a set of window controls as deemed appropriate by
|
||||
* the party managing them, such as user interface components used to move,
|
||||
* resize and change a window's state.
|
||||
*
|
||||
* A client can use this protocol to request being decorated by a supporting
|
||||
* compositor.
|
||||
*
|
||||
* If compositor and client do not negotiate the use of a server-side
|
||||
* decoration using this protocol, clients continue to self-decorate as they
|
||||
* see fit.
|
||||
*
|
||||
* Warning! The protocol described in this file is experimental and
|
||||
* backward incompatible changes may be made. Backward compatible changes
|
||||
* may be added together with the corresponding interface version bump.
|
||||
* Backward incompatible changes are done by bumping the version number in
|
||||
* the protocol and interface names and resetting the interface version.
|
||||
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
* version number in the protocol and interface names are removed and the
|
||||
* interface version number is reset.
|
||||
* @section page_iface_zxdg_decoration_manager_v1_api API
|
||||
* See @ref iface_zxdg_decoration_manager_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface
|
||||
*
|
||||
* This interface allows a compositor to announce support for server-side
|
||||
* decorations.
|
||||
*
|
||||
* A window decoration is a set of window controls as deemed appropriate by
|
||||
* the party managing them, such as user interface components used to move,
|
||||
* resize and change a window's state.
|
||||
*
|
||||
* A client can use this protocol to request being decorated by a supporting
|
||||
* compositor.
|
||||
*
|
||||
* If compositor and client do not negotiate the use of a server-side
|
||||
* decoration using this protocol, clients continue to self-decorate as they
|
||||
* see fit.
|
||||
*
|
||||
* Warning! The protocol described in this file is experimental and
|
||||
* backward incompatible changes may be made. Backward compatible changes
|
||||
* may be added together with the corresponding interface version bump.
|
||||
* Backward incompatible changes are done by bumping the version number in
|
||||
* the protocol and interface names and resetting the interface version.
|
||||
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
* version number in the protocol and interface names are removed and the
|
||||
* interface version number is reset.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_decoration_manager_v1_interface;
|
||||
#endif
|
||||
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1
|
||||
* @section page_iface_zxdg_toplevel_decoration_v1_desc Description
|
||||
*
|
||||
* The decoration object allows the compositor to toggle server-side window
|
||||
* decorations for a toplevel surface. The client can request to switch to
|
||||
* another mode.
|
||||
*
|
||||
* The xdg_toplevel_decoration object must be destroyed before its
|
||||
* xdg_toplevel.
|
||||
* @section page_iface_zxdg_toplevel_decoration_v1_api API
|
||||
* See @ref iface_zxdg_toplevel_decoration_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface
|
||||
*
|
||||
* The decoration object allows the compositor to toggle server-side window
|
||||
* decorations for a toplevel surface. The client can request to switch to
|
||||
* another mode.
|
||||
*
|
||||
* The xdg_toplevel_decoration object must be destroyed before its
|
||||
* xdg_toplevel.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
|
||||
#endif
|
||||
|
||||
#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0
|
||||
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_decoration_manager_v1
|
||||
*/
|
||||
#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_decoration_manager_v1
|
||||
*/
|
||||
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zxdg_decoration_manager_v1 */
|
||||
static inline void
|
||||
zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zxdg_decoration_manager_v1 */
|
||||
static inline void *
|
||||
zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_decoration_manager_v1
|
||||
*
|
||||
* Destroy the decoration manager. This doesn't destroy objects created
|
||||
* with the manager.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
|
||||
ZXDG_DECORATION_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_decoration_manager_v1
|
||||
*
|
||||
* Create a new decoration object associated with the given toplevel.
|
||||
*
|
||||
* Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
|
||||
* buffer attached or committed is a client error, and any attempts by a
|
||||
* client to attach or manipulate a buffer prior to the first
|
||||
* xdg_toplevel_decoration.configure event must also be treated as
|
||||
* errors.
|
||||
*/
|
||||
static inline struct zxdg_toplevel_decoration_v1 *
|
||||
zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
|
||||
ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), 0, NULL, toplevel);
|
||||
|
||||
return (struct zxdg_toplevel_decoration_v1 *) id;
|
||||
}
|
||||
|
||||
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
|
||||
enum zxdg_toplevel_decoration_v1_error {
|
||||
/**
|
||||
* xdg_toplevel has a buffer attached before configure
|
||||
*/
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0,
|
||||
/**
|
||||
* xdg_toplevel already has a decoration object
|
||||
*/
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1,
|
||||
/**
|
||||
* xdg_toplevel destroyed before the decoration object
|
||||
*/
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2,
|
||||
};
|
||||
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */
|
||||
|
||||
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
* window decoration modes
|
||||
*
|
||||
* These values describe window decoration modes.
|
||||
*/
|
||||
enum zxdg_toplevel_decoration_v1_mode {
|
||||
/**
|
||||
* no server-side window decoration
|
||||
*/
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1,
|
||||
/**
|
||||
* server-side window decoration
|
||||
*/
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2,
|
||||
};
|
||||
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
* @struct zxdg_toplevel_decoration_v1_listener
|
||||
*/
|
||||
struct zxdg_toplevel_decoration_v1_listener {
|
||||
/**
|
||||
* notify a decoration mode change
|
||||
*
|
||||
* The configure event configures the effective decoration mode.
|
||||
* The configured state should not be applied immediately. Clients
|
||||
* must send an ack_configure in response to this event. See
|
||||
* xdg_surface.configure and xdg_surface.ack_configure for details.
|
||||
*
|
||||
* A configure event can be sent at any time. The specified mode
|
||||
* must be obeyed by the client.
|
||||
* @param mode the decoration mode
|
||||
*/
|
||||
void (*configure)(void *data,
|
||||
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||
uint32_t mode);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*/
|
||||
static inline int
|
||||
zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||
const struct zxdg_toplevel_decoration_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*/
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*/
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*/
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*/
|
||||
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
|
||||
static inline void
|
||||
zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
|
||||
static inline void *
|
||||
zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*
|
||||
* Switch back to a mode without any server-side decorations at the next
|
||||
* commit.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*
|
||||
* Set the toplevel surface decoration mode. This informs the compositor
|
||||
* that the client prefers the provided decoration mode.
|
||||
*
|
||||
* After requesting a decoration mode, the compositor will respond by
|
||||
* emitting an xdg_surface.configure event. The client should then update
|
||||
* its content, drawing it without decorations if the received mode is
|
||||
* server-side decorations. The client must also acknowledge the configure
|
||||
* when committing the new content (see xdg_surface.ack_configure).
|
||||
*
|
||||
* The compositor can decide not to use the client's mode and enforce a
|
||||
* different mode instead.
|
||||
*
|
||||
* Clients whose decoration mode depend on the xdg_toplevel state may send
|
||||
* a set_mode request in response to an xdg_surface.configure event and wait
|
||||
* for the next xdg_surface.configure event to prevent unwanted state.
|
||||
* Such clients are responsible for preventing configure loops and must
|
||||
* make sure not to send multiple successive set_mode requests with the
|
||||
* same decoration mode.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||
*
|
||||
* Unset the toplevel surface decoration mode. This informs the compositor
|
||||
* that the client doesn't prefer a particular decoration mode.
|
||||
*
|
||||
* This request has the same semantics as set_mode.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -3,9 +3,11 @@
|
||||
#if defined(_M_AMD64) || defined(_M_X64) || defined(__x86_64__)
|
||||
#define EHS_LITTLE_ENDIAN
|
||||
#define EHS_ARCH_X64
|
||||
#define EHS_64_BIT
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||
#define EHS_LITTLE_ENDIAN
|
||||
#define EHS_LITTLE_ENDIAN
|
||||
#define EHS_ARCH_ARM64
|
||||
#define EHS_64_BIT
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
564
src/EHS.cpp
564
src/EHS.cpp
@@ -2,11 +2,12 @@
|
||||
#include "ehs/Log.h"
|
||||
#include "ehs/Version.h"
|
||||
#include "ehs/io/Console.h"
|
||||
#include "ehs/GarbageCollector.h"
|
||||
#include "ehs/GC.h"
|
||||
#include "ehs/io/audio/Audio.h"
|
||||
#include "ehs/io/img/Img.h"
|
||||
#include "ehs/io/img/PNG.h"
|
||||
#include "ehs/io/RIFF.h"
|
||||
#include "ehs/io/mdl/Mdl.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
@@ -94,557 +95,12 @@ namespace ehs
|
||||
{
|
||||
return appVer;
|
||||
}
|
||||
|
||||
bool DecodeWAV(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Audio* out)
|
||||
{
|
||||
RIFF riff(in);
|
||||
|
||||
if (riff.GetType() != "WAVE")
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Data is not in WAVE format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RIFF_Chunk fmt = riff.GetChunk("fmt ");
|
||||
if (!fmt.IsValid())
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Wave does not have a format chunk.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serializer<> fmtSer = fmt.GetData();
|
||||
|
||||
RIFF_Chunk dChunk = riff.GetChunk("data");
|
||||
if (!dChunk.IsValid())
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Wave does not have a data chunk.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_16 compression = fmtSer.Read<UInt_16>();
|
||||
if (compression == 0x2)
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Microsoft ADPCM compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x6)
|
||||
{
|
||||
EHS_LOG_INT("Error", 4, "ITU G.711 a-law compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x7)
|
||||
{
|
||||
EHS_LOG_INT("Error", 5, "ITU G.711 µ-law compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x11)
|
||||
{
|
||||
EHS_LOG_INT("Error", 6, "IMA ADPCM compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x16)
|
||||
{
|
||||
EHS_LOG_INT("Error", 7, "TU G.723 ADPCM (Yamaha) compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x31)
|
||||
{
|
||||
EHS_LOG_INT("Error", 8, "GSM 6.10 compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x40)
|
||||
{
|
||||
EHS_LOG_INT("Error", 9, "ITU G.721 ADPCM compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x50)
|
||||
{
|
||||
EHS_LOG_INT("Error", 10, "MPEG compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0xFFFF)
|
||||
{
|
||||
EHS_LOG_INT("Error", 11, "Experimental compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression != 0x1 && compression != 0x3)
|
||||
{
|
||||
EHS_LOG_INT("Error", 12, "Wave has unknown compression of " + Str_8::FromNum(compression) + ".");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_16 channels = fmtSer.Read<UInt_16>();
|
||||
UInt_32 sampleRate = fmtSer.Read<UInt_32>();
|
||||
fmtSer.SetOffset(fmtSer.GetOffset() + 6);
|
||||
UInt_8 byteDepth = (UInt_8)(fmtSer.Read<UInt_16>() / 8);
|
||||
|
||||
DataType dataType;
|
||||
if (byteDepth == 1)
|
||||
dataType = DataType::SINT_8;
|
||||
else if (byteDepth == 2)
|
||||
dataType = DataType::SINT_16;
|
||||
else if (byteDepth == 3)
|
||||
dataType = DataType::SINT_24;
|
||||
else if (byteDepth == 4 && compression == 0x3)
|
||||
dataType = DataType::FLOAT;
|
||||
else if (byteDepth == 4)
|
||||
dataType = DataType::SINT_32;
|
||||
else if (byteDepth == 8)
|
||||
dataType = DataType::SINT_64;
|
||||
else
|
||||
return false;
|
||||
|
||||
UInt_64 size = dChunk.GetData().Size();
|
||||
UInt_64 frames = size / byteDepth / channels;
|
||||
|
||||
*out = std::move(Audio(out->GetId(), sampleRate, dataType, channels, frames));
|
||||
|
||||
Serializer<> dataSer = dChunk.GetData();
|
||||
|
||||
for (UInt_32 i = 0; i < dataSer.Size(); i += byteDepth)
|
||||
{
|
||||
if (byteDepth == 1)
|
||||
{
|
||||
*(SInt_8*)&(*out)[i] = dataSer.Read<SInt_8>();
|
||||
if ((*out)[i] > *(SInt_8*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_8), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 2)
|
||||
{
|
||||
*(SInt_16*)&(*out)[i] = dataSer.Read<SInt_16>();
|
||||
if (*(SInt_16*)&(*out)[i] > *(SInt_16*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_16), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 3)
|
||||
{
|
||||
*(SInt_16*)&(*out)[i + 1] = dataSer.Read<SInt_16>();
|
||||
(*out)[i] = dataSer.Read<Byte>();
|
||||
|
||||
SInt_32 signal = 0;
|
||||
signal |= (*out)[i];
|
||||
signal |= (*out)[i + 1] << 8;
|
||||
signal |= (*out)[i + 2] << 16;
|
||||
|
||||
SInt_32 peak = 0;
|
||||
peak |= out->GetPeak()[0];
|
||||
peak |= out->GetPeak()[1] << 8;
|
||||
peak |= out->GetPeak()[2] << 16;
|
||||
|
||||
if (signal > peak)
|
||||
out->SetPeak(3, &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 4 && compression == 0x3)
|
||||
{
|
||||
*(float*)&(*out)[i] = dataSer.Read<float>();
|
||||
if (*(float*)&(*out)[i] > *(float*)out->GetPeak())
|
||||
out->SetPeak(sizeof(float), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 4)
|
||||
{
|
||||
*(SInt_32*)&(*out)[i] = dataSer.Read<SInt_32>();
|
||||
if (*(SInt_32*)&(*out)[i] > *(SInt_32*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_32), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 8)
|
||||
{
|
||||
*(SInt_64*)&(*out)[i] = dataSer.Read<SInt_64>();
|
||||
if (*(SInt_64*)&(*out)[i] > *(SInt_64*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_64), &(*out)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EncodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Audio* in)
|
||||
{
|
||||
Serializer<UInt_64> result(codec->GetEndianness());
|
||||
result.WriteVersion({1, 0, 0});
|
||||
result.Write(in->GetSampleRate());
|
||||
result.Write(in->GetDataType());
|
||||
result.Write(in->GetByteDepth());
|
||||
result.Write(in->GetChannels());
|
||||
result.Write(in->GetFrameCount());
|
||||
|
||||
UInt_64 size = in->GetSize();
|
||||
UInt_8 byteDepth = in->GetByteDepth();
|
||||
|
||||
result.Resize(result.Size() + size + byteDepth);
|
||||
Util::Copy(&result[result.GetOffset()], &in[0], size);
|
||||
result.SetOffset(result.GetOffset() + size);
|
||||
|
||||
Util::Copy(&result[result.GetOffset()], in->GetPeak(), byteDepth);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Audio* out)
|
||||
{
|
||||
Version version = in.ReadVersion();
|
||||
if (version != Version(1, 0, 0))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Incompatible audio file version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_64 sampleRate = in.Read<UInt_64>();
|
||||
DataType dataType = in.Read<DataType>();
|
||||
UInt_8 byteDepth = in.Read<UInt_8>();
|
||||
UInt_8 channels = in.Read<UInt_8>();
|
||||
UInt_64 frames = in.Read<UInt_64>();
|
||||
|
||||
*out = Audio(out->GetId(), sampleRate, dataType, channels, frames);
|
||||
|
||||
UInt_64 size = out->GetSize();
|
||||
Util::Copy(&(*out)[0], &in[in.GetOffset()], size);
|
||||
in.SetOffset(in.GetOffset() + size);
|
||||
|
||||
out->SetPeak(byteDepth, &in[in.GetOffset()]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodePNG(const ehs::ImgCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Img* out)
|
||||
{
|
||||
PNG png(out->GetId(), in);
|
||||
|
||||
PNG_Chunk* ihdr = png.GetChunk("IHDR");
|
||||
Serializer<UInt_64>* ihdrData = ihdr->GetData();
|
||||
|
||||
UInt_32 width = ihdrData->Read<UInt_32>();
|
||||
UInt_32 height = ihdrData->Read<UInt_32>();
|
||||
UInt_8 bitDepth = ihdrData->Read<UInt_8>();
|
||||
|
||||
UInt_8 colorType = ihdrData->Read<UInt_8>();
|
||||
if (colorType == 3)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Color type of " + Str_8::FromNum(colorType) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_8 channels = 1;
|
||||
if (colorType == 2)
|
||||
channels = 3;
|
||||
else if (colorType == 4)
|
||||
channels = 2;
|
||||
else if (colorType == 6)
|
||||
channels = 4;
|
||||
|
||||
*out = Img(out->GetId(), bitDepth, channels, {width, height});
|
||||
|
||||
UInt_8 compression = ihdrData->Read<UInt_8>();
|
||||
if (compression)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Compression method of " + Str_8::FromNum(compression) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_8 filter = ihdrData->Read<UInt_8>();
|
||||
if (filter)
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Filter method of " + Str_8::FromNum(filter) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_8 interlaced = ihdrData->Read<UInt_8>();
|
||||
if (interlaced)
|
||||
{
|
||||
EHS_LOG_INT("Error", 4, "Interlacing method of " + Str_8::FromNum(interlaced) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_32 scanline = width * (bitDepth / 8) * channels;
|
||||
UInt_32 scanLineF = scanline + 1;
|
||||
UInt_32 bufferSize = scanline * height + height;
|
||||
|
||||
Byte* buffer = new Byte[bufferSize];
|
||||
|
||||
PNG_Chunk* idat = png.GetChunk("IDAT");
|
||||
Serializer<UInt_64>* idatData = idat->GetData();
|
||||
|
||||
z_stream strm = {};
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = idatData->Size();
|
||||
strm.next_in = *idatData;
|
||||
strm.avail_out = bufferSize;
|
||||
strm.next_out = buffer;
|
||||
|
||||
int code = inflateInit(&strm);
|
||||
if (code != Z_OK)
|
||||
{
|
||||
EHS_LOG_INT("Error", 5, "Failed to initialize zlib inflate with error #" + Str_8::FromNum(code) + ".");
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
code = inflate(&strm, Z_NO_FLUSH);
|
||||
if (code != Z_STREAM_END && code != Z_OK)
|
||||
{
|
||||
EHS_LOG_INT("Error", 6, "Failed to zlib inflate with error #" + Str_8::FromNum(code) + ".");
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
} while (strm.avail_out);
|
||||
|
||||
code = inflateEnd(&strm);
|
||||
if (code != Z_OK)
|
||||
{
|
||||
EHS_LOG_INT("Error", 7, "Failed to uninitialize zlib inflate with error #" + Str_8::FromNum(code) + ".");
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (UInt_32 i = 0, o = 0; i < bufferSize; i += scanLineF, o += scanline)
|
||||
{
|
||||
UInt_8 fCode = buffer[i];
|
||||
if (fCode == 0)
|
||||
PNG::FilterNone(&buffer[i + 1], &(*out)[o], bitDepth, channels, scanline);
|
||||
else if (fCode == 1)
|
||||
PNG::FilterSub(&buffer[i + 1], &(*out)[o], bitDepth, channels, scanline);
|
||||
else if (fCode == 2)
|
||||
PNG::FilterUp(&buffer[i + 1], &(*out)[o - scanline], bitDepth, channels, scanline);
|
||||
else if (fCode == 3)
|
||||
PNG::FilterAverage(&buffer[i + 1], &(*out)[o - scanline], bitDepth, channels, scanline);
|
||||
else if (fCode == 4)
|
||||
PNG::FilterPaeth(&buffer[i + 1], &(*out)[o - scanline], bitDepth, channels, scanline);
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EncodeQOI(const ehs::ImgCodec* const codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Img* in)
|
||||
{
|
||||
UInt_8 channels = in->GetChannels();
|
||||
Vec2_u64 resolution = in->GetResolution();
|
||||
|
||||
UInt_32 px_len = resolution.x * resolution.y * channels;
|
||||
UInt_32 px_end = px_len - channels;
|
||||
|
||||
Byte index[256];
|
||||
for (UInt_64 i = 0; i < 64; ++i)
|
||||
*(UInt_32*)&index[i * 4] = 0;
|
||||
|
||||
Byte prevPixel[4] = {0, 0, 0, 255};
|
||||
Byte pixel[4] = {0, 0, 0, 255};
|
||||
|
||||
Serializer<UInt_32> result(Endianness::BE, resolution.x * resolution.y * (channels + 1) + 22);
|
||||
|
||||
result.Write('q');
|
||||
result.Write('o');
|
||||
result.Write('i');
|
||||
result.Write('f');
|
||||
result.Write<UInt_32>(resolution.x);
|
||||
result.Write<UInt_32>(resolution.y);
|
||||
result.Write(in->GetChannels());
|
||||
result.Write(1);
|
||||
|
||||
for (UInt_32 px_pos = 0, run = 0; px_pos < px_len; px_pos += channels)
|
||||
{
|
||||
if (channels == 4)
|
||||
{
|
||||
*(UInt_32*)pixel = *(UInt_32*)&(*in)[px_pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel[0] = (*in)[px_pos];
|
||||
pixel[1] = (*in)[px_pos + 1];
|
||||
pixel[2] = (*in)[px_pos + 2];
|
||||
}
|
||||
|
||||
if (*(UInt_32*)pixel == *(UInt_32*)prevPixel)
|
||||
{
|
||||
run++;
|
||||
if (run == 62 || px_pos == px_end)
|
||||
{
|
||||
result.Write<UInt_8>(0xc0 | (run - 1));
|
||||
run = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (run > 0)
|
||||
{
|
||||
result.Write<UInt_8>(0xc0 | (run - 1));
|
||||
run = 0;
|
||||
}
|
||||
|
||||
UInt_32 index_pos = (prevPixel[0] * 3 + prevPixel[1] * 5 + prevPixel[2] * 7 + prevPixel[3] * 11) % 64 * channels;
|
||||
|
||||
if (*(UInt_32*)&index[index_pos] == *(UInt_32*)pixel)
|
||||
{
|
||||
result.Write<UInt_8>(0x00 | (index_pos / channels));
|
||||
}
|
||||
else
|
||||
{
|
||||
*(UInt_32*)&index[index_pos] = *(UInt_32*)pixel;
|
||||
|
||||
if (pixel[3] == prevPixel[3])
|
||||
{
|
||||
SInt_8 vr = pixel[0] - prevPixel[0];
|
||||
SInt_8 vg = pixel[1] - prevPixel[1];
|
||||
SInt_8 vb = pixel[2] - prevPixel[2];
|
||||
|
||||
SInt_8 vg_r = vr - vg;
|
||||
SInt_8 vg_b = vb - vg;
|
||||
|
||||
if (
|
||||
vr > -3 && vr < 2 &&
|
||||
vg > -3 && vg < 2 &&
|
||||
vb > -3 && vb < 2
|
||||
)
|
||||
{
|
||||
result.Write<UInt_8>(0x40 | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2));
|
||||
}
|
||||
else if (
|
||||
vg_r > -9 && vg_r < 8 &&
|
||||
vg > -33 && vg < 32 &&
|
||||
vg_b > -9 && vg_b < 8
|
||||
)
|
||||
{
|
||||
result.Write<UInt_8>(0x80 | (vg + 32));
|
||||
result.Write<UInt_8>((vg_r + 8) << 4 | (vg_b + 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Write<UInt_8>(0xfe);
|
||||
result.Write(pixel[0]);
|
||||
result.Write(pixel[1]);
|
||||
result.Write(pixel[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Write<UInt_8>(0xff);
|
||||
result.SetEndianness(CPU::GetEndianness());
|
||||
result.Write(*(UInt_32*)pixel);
|
||||
result.SetEndianness(Endianness::BE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*(UInt_32*)prevPixel = *(UInt_32*)pixel;
|
||||
}
|
||||
|
||||
result.Write(0x100000000000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeQOI(const ehs::ImgCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Img* out)
|
||||
{
|
||||
Str_8 imgType = in.ReadStr<Char_8, UInt_64>(4);
|
||||
if (imgType != "qoif")
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Given data is not in the qoif format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_64 width = in.Read<UInt_32>();
|
||||
UInt_64 height = in.Read<UInt_32>();
|
||||
|
||||
UInt_8 channels = in.Read<UInt_8>();
|
||||
channels = 4;
|
||||
UInt_8 space = in.Read<UInt_8>();
|
||||
UInt_8 bitDepth = 8;
|
||||
|
||||
UInt_64 size = width * channels * height;
|
||||
|
||||
*out = Img(out->GetId(), bitDepth, channels, {width, height});
|
||||
|
||||
Byte prevPixel[4] = {0, 0, 0, 255};
|
||||
|
||||
Byte index[256];
|
||||
for (UInt_64 i = 0; i < 64; ++i)
|
||||
*(UInt_32*)&index[i * 4] = 0;
|
||||
|
||||
UInt_32 chunksLen = in.Size() - 8;
|
||||
for (UInt_32 pos = 0, run = 0; pos < size; pos += channels)
|
||||
{
|
||||
if (run > 0)
|
||||
--run;
|
||||
else if (in.GetOffset() < chunksLen)
|
||||
{
|
||||
UInt_32 chunkType = (UInt_32)in.Read<UInt_8>();
|
||||
if (chunkType == 0xfe) // RGB
|
||||
{
|
||||
prevPixel[0] = in.Read<UInt_8>(); // R-value
|
||||
prevPixel[1] = in.Read<UInt_8>(); // G-value
|
||||
prevPixel[2] = in.Read<UInt_8>(); // B-value
|
||||
}
|
||||
else if (chunkType == 0xff) // RGBA
|
||||
{
|
||||
*(UInt_32*)prevPixel = in.Read<UInt_32>();
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0x00) // Index
|
||||
{
|
||||
*(UInt_32*)prevPixel = *(UInt_32*)&index[chunkType * channels];
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0x40) // Diff
|
||||
{
|
||||
prevPixel[0] += ((chunkType >> 4) & 0x03) - 2; // R-value
|
||||
prevPixel[1] += ((chunkType >> 2) & 0x03) - 2; // G-value
|
||||
prevPixel[2] += (chunkType & 0x03) - 2; // B-value
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0x80) // Luma
|
||||
{
|
||||
UInt_32 mod = (UInt_32)in.Read<UInt_8>();
|
||||
UInt_32 vg = (chunkType & 0x3f) - 32;
|
||||
prevPixel[0] += vg - 8 + ((mod >> 4) & 0x0f); // R-value
|
||||
prevPixel[1] += vg; // G-value
|
||||
prevPixel[2] += vg - 8 + (mod & 0x0f); // B-value
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0xc0) // Run
|
||||
run = (chunkType & 0x3f);
|
||||
|
||||
*(UInt_32*)&index[(prevPixel[0] * 3 + prevPixel[1] * 5 + prevPixel[2] * 7 + prevPixel[3] * 11) % 64 * channels] = *(UInt_32*)prevPixel;
|
||||
}
|
||||
|
||||
if (channels == 4)
|
||||
{
|
||||
*((UInt_32*)&(*out)[pos]) = *(UInt_32*)prevPixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*out)[pos] = prevPixel[0];
|
||||
(*out)[pos + 1] = prevPixel[1];
|
||||
(*out)[pos + 2] = prevPixel[2];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void LogRaised(const ehs::Log& log)
|
||||
{
|
||||
ehs::Array<ehs::Str_8> tags = log.GetTags();
|
||||
|
||||
ehs::Str_8 result = "{";
|
||||
|
||||
for (ehs::UInt_32 i = 0; i < tags.Size(); ++i)
|
||||
{
|
||||
result += tags[i];
|
||||
if (i != tags.Size() - 1)
|
||||
result += ", ";
|
||||
}
|
||||
|
||||
result += "} (" + ehs::Str_8::FromNum(log.GetCode()) + "): " + log.GetMsg();
|
||||
|
||||
ehs::Console::Write_8(result);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ehs::Console::Attach();
|
||||
|
||||
ehs::Log::SetCallback(LogRaised);
|
||||
|
||||
ehs::Audio::AddCodec({
|
||||
"Waveform Audio",
|
||||
"wav",
|
||||
@@ -677,13 +133,23 @@ int main()
|
||||
ehs::DecodeQOI
|
||||
});
|
||||
|
||||
ehs::GarbageCollector::Start();
|
||||
ehs::Mdl::AddCodec({
|
||||
"Event Horizon Model",
|
||||
"ehm",
|
||||
ehs::Endianness::LE,
|
||||
ehs::EncodeEHM,
|
||||
ehs::DecodeEHM
|
||||
});
|
||||
|
||||
ehs::GC::Start();
|
||||
|
||||
const ehs::SInt_32 code = Main(&ehs::appName, &ehs::appVerId, &ehs::appVer);
|
||||
if (code)
|
||||
EHS_LOG("Warning", 0, "Executable exited with code #" + ehs::Str_8::FromNum(code) + ".");
|
||||
EHS_LOG_INT(ehs::LogType::WARN, 0, "Executable exited with code #" + ehs::Str_8::FromNum(code) + ".");
|
||||
|
||||
ehs::GarbageCollector::Stop();
|
||||
ehs::GC::Stop();
|
||||
|
||||
ehs::Log::OnExit();
|
||||
|
||||
return code;
|
||||
}
|
180
src/GC.cpp
Normal file
180
src/GC.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include "ehs/GC.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
UInt_32 GarbageCollectionThread(void* params)
|
||||
{
|
||||
while (GC::IsRunning())
|
||||
{
|
||||
GC::Poll();
|
||||
Thread::SleepFor(50);
|
||||
}
|
||||
|
||||
GC::Dump();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Array<GcLogic> GC::logic;
|
||||
Vector<BaseObj*> GC::garbage(0, 1000);
|
||||
UInt_64 GC::max = 10;
|
||||
Thread GC::thread;
|
||||
Mutex GC::mutex;
|
||||
bool GC::running = false;
|
||||
|
||||
bool GC::Has(const BaseObj* obj)
|
||||
{
|
||||
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
||||
if (garbage[i] == obj)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GC::Start()
|
||||
{
|
||||
if (running)
|
||||
return;
|
||||
|
||||
mutex.Initialize();
|
||||
|
||||
thread.Start(GarbageCollectionThread, nullptr);
|
||||
|
||||
running = true;
|
||||
}
|
||||
|
||||
void GC::Stop()
|
||||
{
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
running = false;
|
||||
|
||||
thread.Join();
|
||||
}
|
||||
|
||||
bool GC::HasLogic(GcLogic logicCb)
|
||||
{
|
||||
for (UInt_64 i = 0; i < logic.Size(); ++i)
|
||||
if (logic[i] == logicCb)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GC::AddLogic(GcLogic logicCb)
|
||||
{
|
||||
if (HasLogic(logicCb))
|
||||
return false;
|
||||
|
||||
if (running)
|
||||
mutex.Lock();
|
||||
|
||||
logic.Push(logicCb);
|
||||
|
||||
if (running)
|
||||
mutex.Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GC::Add(BaseObj* obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
#ifdef EHS_DEBUG
|
||||
if (Has(obj))
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, Str_8(obj->GetTypeId(), obj->GetTypeIdSize()) +
|
||||
" object with address of, \"" + Str_8::FromNum((ehs::Size)obj) + "\" is already in garbage.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
garbage.Push(obj);
|
||||
}
|
||||
|
||||
void GC::SetMax(const UInt_64 newMax)
|
||||
{
|
||||
max = newMax;
|
||||
}
|
||||
|
||||
UInt_64 GC::GetMax()
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
void GC::SetStride(const UInt_64 newStride)
|
||||
{
|
||||
Dump();
|
||||
|
||||
garbage = Vector<BaseObj*>(0, newStride);
|
||||
}
|
||||
|
||||
UInt_64 GC::GetStride()
|
||||
{
|
||||
return garbage.Stride();
|
||||
}
|
||||
|
||||
UInt_64 GC::Size()
|
||||
{
|
||||
return garbage.Size();
|
||||
}
|
||||
|
||||
void GC::Poll()
|
||||
{
|
||||
if (running)
|
||||
mutex.Lock();
|
||||
|
||||
UInt_64 i = 0;
|
||||
UInt_64 o = 0;
|
||||
|
||||
while (garbage.Size() && i < max && o < garbage.Size())
|
||||
{
|
||||
if (!ShouldDelete(garbage[o]))
|
||||
{
|
||||
o++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (o != garbage.Size() - 1)
|
||||
garbage.Swap(o, garbage.End());
|
||||
|
||||
delete garbage.Pop();
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (running)
|
||||
mutex.Unlock();
|
||||
}
|
||||
|
||||
void GC::Dump()
|
||||
{
|
||||
if (running)
|
||||
mutex.Lock();
|
||||
|
||||
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
||||
delete garbage[i];
|
||||
|
||||
garbage.Clear();
|
||||
|
||||
if (running)
|
||||
mutex.Unlock();
|
||||
}
|
||||
|
||||
bool GC::IsRunning()
|
||||
{
|
||||
return running;
|
||||
}
|
||||
|
||||
bool GC::ShouldDelete(BaseObj *obj)
|
||||
{
|
||||
for (UInt_64 l = 0; l < logic.Size(); ++l)
|
||||
if (!logic[l](obj))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,133 +0,0 @@
|
||||
#include "ehs/GarbageCollector.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
UInt_32 GarbageCollectionThread(void* params)
|
||||
{
|
||||
while (GarbageCollector::IsRunning())
|
||||
{
|
||||
GarbageCollector::Poll();
|
||||
Thread::SleepFor(50);
|
||||
}
|
||||
|
||||
GarbageCollector::Dump();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vector<BaseObj*> GarbageCollector::garbage(0, 1000);
|
||||
UInt_64 GarbageCollector::max = 10;
|
||||
Thread GarbageCollector::thread;
|
||||
Mutex GarbageCollector::mutex;
|
||||
bool GarbageCollector::running = false;
|
||||
|
||||
bool GarbageCollector::Has(const BaseObj* obj)
|
||||
{
|
||||
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
||||
if (garbage[i] == obj)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GarbageCollector::Start()
|
||||
{
|
||||
if (running)
|
||||
return;
|
||||
|
||||
mutex.Initialize();
|
||||
|
||||
thread.Start(GarbageCollectionThread, nullptr);
|
||||
|
||||
running = true;
|
||||
}
|
||||
|
||||
void GarbageCollector::Stop()
|
||||
{
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
running = false;
|
||||
|
||||
thread.Join();
|
||||
}
|
||||
|
||||
void GarbageCollector::Add(BaseObj* obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
/*
|
||||
if (Has(obj))
|
||||
{
|
||||
EHS_LOG_INT("Warning", 1, obj->GetTypeId() + " object with address of, \"" + Str_8::FromNum<USize>((USize)obj) + "\" is already in garbage.");
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
garbage.Push(obj);
|
||||
}
|
||||
|
||||
void GarbageCollector::SetMax(const UInt_64 newMax)
|
||||
{
|
||||
max = newMax;
|
||||
}
|
||||
|
||||
UInt_64 GarbageCollector::GetMax()
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
void GarbageCollector::SetStride(const UInt_64 newStride)
|
||||
{
|
||||
Dump();
|
||||
|
||||
garbage = Vector<BaseObj*>(0, newStride);
|
||||
}
|
||||
|
||||
UInt_64 GarbageCollector::GetStride()
|
||||
{
|
||||
return garbage.Stride();
|
||||
}
|
||||
|
||||
UInt_64 GarbageCollector::Size()
|
||||
{
|
||||
return garbage.Size();
|
||||
}
|
||||
|
||||
void GarbageCollector::Poll()
|
||||
{
|
||||
if (running)
|
||||
mutex.Lock();
|
||||
|
||||
UInt_64 i = 0;
|
||||
|
||||
while (i < garbage.Size())
|
||||
{
|
||||
garbage.Swap(i, garbage.End());
|
||||
delete garbage.Pop();
|
||||
}
|
||||
|
||||
if (running)
|
||||
mutex.Unlock();
|
||||
}
|
||||
|
||||
void GarbageCollector::Dump()
|
||||
{
|
||||
if (running)
|
||||
mutex.Lock();
|
||||
|
||||
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
||||
delete garbage[i];
|
||||
|
||||
garbage.Clear();
|
||||
|
||||
if (running)
|
||||
mutex.Unlock();
|
||||
}
|
||||
|
||||
bool GarbageCollector::IsRunning()
|
||||
{
|
||||
return running;
|
||||
}
|
||||
}
|
143
src/Log.cpp
143
src/Log.cpp
@@ -1,58 +1,127 @@
|
||||
#include "ehs/Log.h"
|
||||
|
||||
#include "ehs/io/Console.h"
|
||||
#include "ehs/io/File.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
void (*Log::logCb)(const Log&) = nullptr;
|
||||
Log Log::lastLog;
|
||||
|
||||
void Log::SetCallback(void (*newLogCb)(const Log&))
|
||||
void Log::DefaultRaisedCb(const Log &log)
|
||||
{
|
||||
logCb = newLogCb;
|
||||
Console::Write_8(log.ToStr());
|
||||
}
|
||||
|
||||
void Log::Raise(const Log& log)
|
||||
void Log::DefaultOutputCb(const Array<Log> &logs)
|
||||
{
|
||||
if (logCb)
|
||||
logCb(log);
|
||||
File output("Logs.txt", Mode::WRITE, Disposition::CREATE_PERSISTENT);
|
||||
output.SeekBeginning();
|
||||
|
||||
lastLog = log;
|
||||
for (UInt_64 i = 0; i < logs.Size(); ++i)
|
||||
output.WriteStr_8(logs[i].ToStr() + "\n");
|
||||
}
|
||||
|
||||
LogRaisedCb Log::raisedCb = DefaultRaisedCb;
|
||||
LogOutputCb Log::outputCb = DefaultOutputCb;
|
||||
Array<Log> Log::logs;
|
||||
Log Log::lastLog;
|
||||
bool Log::immediate = false;
|
||||
|
||||
void Log::SetRaisedCallback(const LogRaisedCb newCb)
|
||||
{
|
||||
raisedCb = newCb;
|
||||
}
|
||||
|
||||
void Log::SetOutputCallback(const LogOutputCb newCb)
|
||||
{
|
||||
outputCb = newCb;
|
||||
}
|
||||
|
||||
void Log::OnExit()
|
||||
{
|
||||
if (lastLog.GetType() != LogType::SUCCESS)
|
||||
logs.Push(lastLog);
|
||||
|
||||
lastLog = {};
|
||||
|
||||
if (outputCb)
|
||||
outputCb(logs);
|
||||
}
|
||||
|
||||
void Log::Raise(Log log)
|
||||
{
|
||||
if (log.GetType() == LogType::INFO || (log.GetType() != LogType::SUCCESS && immediate))
|
||||
if (raisedCb)
|
||||
raisedCb(log);
|
||||
|
||||
if (lastLog.GetType() != LogType::SUCCESS)
|
||||
logs.Push((Log&&)lastLog);
|
||||
|
||||
lastLog = (Log&&)log;
|
||||
}
|
||||
|
||||
Log Log::GetLastLog()
|
||||
{
|
||||
Log result = lastLog;
|
||||
lastLog = Log();
|
||||
lastLog = {};
|
||||
return result;
|
||||
}
|
||||
|
||||
void Log::EnableImmediateMode(const bool enable)
|
||||
{
|
||||
immediate = enable;
|
||||
}
|
||||
|
||||
Log::Log()
|
||||
: code(0)
|
||||
: type(LogType::SUCCESS), code(0)
|
||||
{
|
||||
}
|
||||
|
||||
Log::Log(std::initializer_list<Str_8> tags, const UInt_64 code, const Str_8& msg)
|
||||
: tags(tags.size()), code(code), msg(msg)
|
||||
Log::Log(LogType type, const std::initializer_list<Str_8> &tags, const UInt_64 code, Str_8 msg)
|
||||
: type(type), tags(tags.size()), code(code), msg((Str_8&&)msg)
|
||||
{
|
||||
UInt_64 i = 0;
|
||||
for (auto v = tags.begin(); v != tags.end(); ++v)
|
||||
this->tags[i++] = *v;
|
||||
}
|
||||
|
||||
Log::Log(Array<Str_8>& tags, const UInt_64 code, const Str_8& msg)
|
||||
: tags(tags), code(code), msg(msg)
|
||||
Log::Log(LogType type, Array<Str_8> tags, const UInt_64 code, Str_8 msg)
|
||||
: type(type), tags((Array<Str_8>&&)tags), code(code), msg((Str_8&&)msg)
|
||||
{
|
||||
}
|
||||
|
||||
Log::Log(const Log& log)
|
||||
: tags(log.tags), code(log.code), msg(log.msg)
|
||||
Log::Log(Log &&log) noexcept
|
||||
: type(log.type), tags((Array<Str_8>&&)log.tags), code(log.code), msg((Str_8&&)log.msg)
|
||||
{
|
||||
log.type = LogType::INFO;
|
||||
log.code = 0;
|
||||
}
|
||||
|
||||
Log::Log(const Log &log)
|
||||
: type(log.type), tags(log.tags), code(log.code), msg(log.msg)
|
||||
{
|
||||
}
|
||||
|
||||
Log& Log::operator=(const Log& log)
|
||||
Log & Log::operator=(Log &&log) noexcept
|
||||
{
|
||||
if (this == &log)
|
||||
return *this;
|
||||
|
||||
type = log.type;
|
||||
tags = (Array<Str_8>&&)log.tags;
|
||||
code = log.code;
|
||||
msg = (Str_8&&)log.msg;
|
||||
|
||||
log.type = LogType::INFO;
|
||||
log.code = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Log& Log::operator=(const Log &log)
|
||||
{
|
||||
if (this == &log)
|
||||
return *this;
|
||||
|
||||
type = log.type;
|
||||
tags = log.tags;
|
||||
code = log.code;
|
||||
msg = log.msg;
|
||||
@@ -72,7 +141,12 @@ namespace ehs
|
||||
}
|
||||
*/
|
||||
|
||||
bool Log::HasTags(const std::initializer_list<Str_8> tags) const
|
||||
LogType Log::GetType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
bool Log::HasTags(const std::initializer_list<Str_8> &tags) const
|
||||
{
|
||||
UInt_64 i = 0;
|
||||
UInt_64 c = 0;
|
||||
@@ -110,7 +184,7 @@ namespace ehs
|
||||
return false;
|
||||
}
|
||||
|
||||
Array<Str_8> Log::GetTags() const
|
||||
const Array<Str_8> &Log::GetTags() const
|
||||
{
|
||||
return tags;
|
||||
}
|
||||
@@ -127,7 +201,32 @@ namespace ehs
|
||||
|
||||
Str_8 Log::ToStr() const
|
||||
{
|
||||
Str_8 result = "[";
|
||||
Str_8 result = "<";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LogType::SUCCESS:
|
||||
{
|
||||
result += "Success";
|
||||
break;
|
||||
}
|
||||
case LogType::ERR:
|
||||
{
|
||||
result += "Error";
|
||||
break;
|
||||
}
|
||||
case LogType::WARN:
|
||||
{
|
||||
result += "Warning";
|
||||
break;
|
||||
}
|
||||
case LogType::INFO:
|
||||
{
|
||||
result += "Information";
|
||||
}
|
||||
}
|
||||
|
||||
result += ">[";
|
||||
|
||||
for (UInt_64 i = 0; i < tags.Size(); ++i)
|
||||
{
|
||||
@@ -146,4 +245,4 @@ namespace ehs
|
||||
{
|
||||
return tags.Size() && msg.Size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -189,7 +189,7 @@ namespace ehs
|
||||
{
|
||||
if (working)
|
||||
{
|
||||
EHS_LOG_INT("Warning", 0, "Attempted to give work while task is still working.");
|
||||
EHS_LOG_INT(LogType::WARN, 0, "Attempted to give work while task is still working.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +0,0 @@
|
||||
#include "ehs/database/DVar.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
}
|
198
src/db/Database.cpp
Normal file
198
src/db/Database.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "ehs/db/Database.h"
|
||||
|
||||
#include "ehs/io/Directory_LNX.h"
|
||||
#include "ehs/io/File.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Database::Database()
|
||||
: hashId(0)
|
||||
{
|
||||
}
|
||||
|
||||
Database::Database(Str_8 id, const Version& version)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), version(version)
|
||||
{
|
||||
}
|
||||
|
||||
Database::Database(Str_8 filePath)
|
||||
{
|
||||
filePath = filePath.ReplaceAll("\\", "/");
|
||||
|
||||
UInt_64 i = 0;
|
||||
if (filePath.Find("/", &i, SearchPattern::RIGHT_LEFT))
|
||||
dir = filePath.Sub(0, i);
|
||||
else
|
||||
dir = "./";
|
||||
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
|
||||
Log log = Log::GetLastLog();
|
||||
if (log.GetType() == LogType::ERR && log.GetCode() == 0)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Database file not found at, \"" + filePath + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
id = file.GetName();
|
||||
hashId = id.Hash_64();
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(Endianness::LE, file.Size());
|
||||
file.Release();
|
||||
|
||||
version = data.ReadVersion();
|
||||
tables.Resize(data.Read<UInt_64>());
|
||||
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
{
|
||||
tables[i].parent = this;
|
||||
tables[i].Deserialize(dir, data);
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
|
||||
Database::Database(Database&& db) noexcept
|
||||
: hashId(db.hashId), id((Str_8&&)db.id), version(db.version), tables((Array<DbTable>&&)db.tables),
|
||||
dir((Str_8&&)db.dir)
|
||||
{
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
tables[i].parent = this;
|
||||
|
||||
db.hashId = 0;
|
||||
db.version = {0, 0, 0};
|
||||
}
|
||||
|
||||
Database::Database(const Database& db)
|
||||
: hashId(db.hashId), id(db.id), version(db.version), tables(db.tables), dir(db.dir)
|
||||
{
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
tables[i].parent = this;
|
||||
}
|
||||
|
||||
Database& Database::operator=(Database&& db) noexcept
|
||||
{
|
||||
if (this == &db)
|
||||
return *this;
|
||||
|
||||
hashId = db.hashId;
|
||||
id = (Str_8&&)db.id;
|
||||
version = db.version;
|
||||
|
||||
tables = (Array<DbTable>&&)db.tables;
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
tables[i].parent = this;
|
||||
|
||||
dir = (Str_8&&)db.dir;
|
||||
|
||||
db.hashId = 0;
|
||||
db.version = {0, 0, 0};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Database& Database::operator=(const Database& db)
|
||||
{
|
||||
if (this == &db)
|
||||
return *this;
|
||||
|
||||
hashId = db.hashId;
|
||||
id = db.id;
|
||||
version = db.version;
|
||||
|
||||
tables = db.tables;
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
tables[i].parent = this;
|
||||
|
||||
dir = db.dir;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt_64 Database::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void Database::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = (Str_8&&)newId;
|
||||
}
|
||||
|
||||
Str_8 Database::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
void Database::SetVersion(const Version& newVersion)
|
||||
{
|
||||
version = newVersion;
|
||||
}
|
||||
|
||||
Version Database::GetVersion() const
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
bool Database::HasTable(UInt_64 hashId) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
if (tables[i].GetHashId() == hashId)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::HasTable(const Str_8& id) const
|
||||
{
|
||||
return HasTable(id.Hash_64());
|
||||
}
|
||||
|
||||
DbTable* Database::CreateTable(Str_8 id)
|
||||
{
|
||||
if (HasTable(id))
|
||||
return nullptr;
|
||||
|
||||
tables.Push(DbTable((Str_8&&)id));
|
||||
|
||||
DbTable *tbl = &tables[tables.End()];
|
||||
tbl->parent = this;
|
||||
return tbl;
|
||||
}
|
||||
|
||||
DbTable* Database::GetTable(UInt_64 hashId) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
if (tables[i].GetHashId() == hashId)
|
||||
return &tables[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DbTable* Database::GetTable(const Str_8& id) const
|
||||
{
|
||||
return GetTable(id.Hash_64());
|
||||
}
|
||||
|
||||
Str_8 Database::GetDirectory() const
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
|
||||
void Database::Save(Str_8 directory)
|
||||
{
|
||||
dir = (Str_8&&)directory;
|
||||
|
||||
Serializer<UInt_64> data(Endianness::LE);
|
||||
data.WriteVersion(version);
|
||||
data.Write(tables.Size());
|
||||
|
||||
Directory::CreateRecursive(dir);
|
||||
|
||||
for (UInt_64 i = 0; i < tables.Size(); ++i)
|
||||
tables[i].Serialize(dir, data);
|
||||
|
||||
File file(dir + "/" + id + ".ehd", Mode::WRITE, Disposition::CREATE_PERSISTENT);
|
||||
file.WriteSerializer_64(data);
|
||||
}
|
||||
}
|
145
src/db/DbObject.cpp
Normal file
145
src/db/DbObject.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "ehs/db/DbObject.h"
|
||||
#include "ehs/db/DbTable.h"
|
||||
#include "ehs/Serializer.h"
|
||||
#include "ehs/db/Database.h"
|
||||
#include "ehs/io/Directory_LNX.h"
|
||||
#include "ehs/io/File.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
DbObject::DbObject()
|
||||
: id(0), parent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
DbObject::DbObject(const UInt_64 id)
|
||||
: id(id), parent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
DbObject::DbObject(DbObject&& obj) noexcept
|
||||
: id(obj.id), parent(obj.parent), vars((Array<DbVar>&&)obj.vars)
|
||||
{
|
||||
obj.id = 0;
|
||||
obj.parent = nullptr;
|
||||
}
|
||||
|
||||
DbObject::DbObject(const DbObject& obj)
|
||||
: id(obj.id), parent(obj.parent), vars(obj.vars)
|
||||
{
|
||||
}
|
||||
|
||||
DbObject& DbObject::operator=(DbObject&& obj) noexcept
|
||||
{
|
||||
if (this == &obj)
|
||||
return *this;
|
||||
|
||||
id = obj.id;
|
||||
parent = obj.parent;
|
||||
vars = (Array<DbVar>&&)obj.vars;
|
||||
|
||||
for (UInt_64 i = 0; i < vars.Size(); ++i)
|
||||
vars[i].parent = this;
|
||||
|
||||
obj.id = 0;
|
||||
obj.parent = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DbObject& DbObject::operator=(const DbObject& obj)
|
||||
{
|
||||
if (this == &obj)
|
||||
return *this;
|
||||
|
||||
id = obj.id;
|
||||
parent = obj.parent;
|
||||
vars = obj.vars;
|
||||
|
||||
for (UInt_64 i = 0; i < vars.Size(); ++i)
|
||||
vars[i].parent = this;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt_64 DbObject::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
bool DbObject::HasVariable(const UInt_64 hashId) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < vars.Size(); ++i)
|
||||
if (vars[i].GetHashId() == hashId)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DbVar* DbObject::GetVariable(const UInt_64 hashId) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < vars.Size(); ++i)
|
||||
if (vars[i].GetHashId() == hashId)
|
||||
return &vars[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DbVar* DbObject::GetVariable(const Str_8& id) const
|
||||
{
|
||||
return GetVariable(id.Hash_64());
|
||||
}
|
||||
|
||||
void DbObject::Save() const
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
|
||||
Serializer<UInt_64> data(Endianness::LE);
|
||||
|
||||
data.Write(vars.Size());
|
||||
|
||||
for (UInt_64 i = 0; i < vars.Size(); ++i)
|
||||
vars[i].Serialize(data);
|
||||
|
||||
Directory::CreateRecursive(parent->parent->GetDirectory() + "/" + parent->GetId());
|
||||
|
||||
File file(parent->parent->GetDirectory() + "/" + parent->GetId() + "/" + Str_8::FromNum(id) + ".eho", Mode::WRITE, Disposition::CREATE_PERSISTENT);
|
||||
file.SeekBeginning();
|
||||
file.WriteSerializer_64(data);
|
||||
}
|
||||
|
||||
void DbObject::Load()
|
||||
{
|
||||
if (IsLoaded())
|
||||
return;
|
||||
|
||||
File file(parent->parent->GetDirectory() + "/" + parent->GetId() + "/" + Str_8::FromNum(id) + ".eho", Mode::READ, Disposition::OPEN);
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(Endianness::LE, file.Size());
|
||||
file.Release();
|
||||
|
||||
vars.Resize(data.Read<UInt_64>());
|
||||
|
||||
for (UInt_64 i = 0; i < vars.Size(); ++i)
|
||||
{
|
||||
vars[i].parent = this;
|
||||
vars[i].Deserialize(data);
|
||||
}
|
||||
}
|
||||
|
||||
bool DbObject::IsLoaded() const
|
||||
{
|
||||
return vars.Size();
|
||||
}
|
||||
|
||||
void DbObject::Free()
|
||||
{
|
||||
vars.Clear();
|
||||
}
|
||||
|
||||
void DbObject::CreateVariable(DbVarTmpl* master)
|
||||
{
|
||||
vars.Push(DbVar(master->GetHashId(), master));
|
||||
vars[vars.End()].parent = this;
|
||||
}
|
||||
}
|
201
src/db/DbTable.cpp
Normal file
201
src/db/DbTable.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
#include "ehs/db/DbTable.h"
|
||||
#include "ehs/db/Database.h"
|
||||
#include "ehs/io/Directory.h"
|
||||
#include "ehs/io/File_UNX.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
DbTable::DbTable()
|
||||
: parent(nullptr), hashId(0)
|
||||
{
|
||||
}
|
||||
|
||||
DbTable::DbTable(Str_8 id)
|
||||
: parent(nullptr), hashId(id.Hash_64()), id((Str_8&&)id)
|
||||
{
|
||||
}
|
||||
|
||||
DbTable::DbTable(DbTable&& table) noexcept
|
||||
: parent(table.parent), hashId(table.hashId), id((Str_8&&)table.id), varTmpls((Array<DbVarTmpl>&&)table.varTmpls),
|
||||
objects((Array<DbObject>&&)table.objects)
|
||||
{
|
||||
table.parent = nullptr;
|
||||
table.hashId = 0;
|
||||
}
|
||||
|
||||
DbTable::DbTable(const DbTable& table)
|
||||
: parent(nullptr), hashId(table.hashId), id(table.id), varTmpls(table.varTmpls), objects(table.objects)
|
||||
{
|
||||
}
|
||||
|
||||
DbTable& DbTable::operator=(DbTable&& table) noexcept
|
||||
{
|
||||
if (this == &table)
|
||||
return *this;
|
||||
|
||||
parent = table.parent;
|
||||
hashId = table.hashId;
|
||||
id = (Str_8&&)table.id;
|
||||
varTmpls = (Array<DbVarTmpl>&&)table.varTmpls;
|
||||
|
||||
objects = (Array<DbObject>&&)table.objects;
|
||||
for (UInt_64 i = 0; i < objects.Size(); ++i)
|
||||
objects[i].parent = this;
|
||||
|
||||
table.parent = nullptr;
|
||||
table.hashId = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DbTable& DbTable::operator=(const DbTable& table)
|
||||
{
|
||||
if (this == &table)
|
||||
return *this;
|
||||
|
||||
parent = nullptr;
|
||||
hashId = table.hashId;
|
||||
id = table.id;
|
||||
varTmpls = table.varTmpls;
|
||||
|
||||
objects = table.objects;
|
||||
for (UInt_64 i = 0; i < objects.Size(); ++i)
|
||||
objects[i].parent = this;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt_64 DbTable::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void DbTable::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = (Str_8&&)newId;
|
||||
}
|
||||
|
||||
Str_8 DbTable::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
bool DbTable::HasVariable(const UInt_64 hashId) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < varTmpls.Size(); ++i)
|
||||
if (varTmpls[i].GetHashId() == hashId)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DbTable::HasVariable(const Str_8& id) const
|
||||
{
|
||||
return HasVariable(id.Hash_64());
|
||||
}
|
||||
|
||||
bool DbTable::CreateVariable(DbVarTmpl var)
|
||||
{
|
||||
if (HasVariable(var.GetHashId()))
|
||||
return false;
|
||||
|
||||
varTmpls.Push((DbVarTmpl&&)var);
|
||||
|
||||
DbVarTmpl* result = &varTmpls[varTmpls.End()];
|
||||
|
||||
for (UInt_64 i = 0; i < objects.Size(); ++i)
|
||||
objects[i].CreateVariable(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DbObject *DbTable::CreateObject()
|
||||
{
|
||||
objects.Push(DbObject(objects.Size()));
|
||||
|
||||
DbObject* obj = &objects[objects.End()];
|
||||
|
||||
obj->parent = this;
|
||||
|
||||
for (UInt_64 i = 0; i < varTmpls.Size(); ++i)
|
||||
obj->CreateVariable(&varTmpls[i]);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
DbObject* DbTable::GetObject(UInt_64 variableHashId, const Str_8& value) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < objects.Size(); ++i)
|
||||
{
|
||||
objects[i].Load();
|
||||
|
||||
const DbVar * const var = objects[i].GetVariable(variableHashId);
|
||||
if (var->GetValueStr() == value)
|
||||
return &objects[i];
|
||||
|
||||
objects[i].Free();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DbObject* DbTable::GetObject(const Str_8& variable, const Str_8& value) const
|
||||
{
|
||||
return GetObject(variable.Hash_64(), value);
|
||||
}
|
||||
|
||||
DbObject* DbTable::GetObject(const UInt_64 id) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < objects.Size(); ++i)
|
||||
if (objects[i].GetId() == id)
|
||||
return &objects[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DbVarTmpl *DbTable::GetVariableTemplate(const UInt_64 hashId) const
|
||||
{
|
||||
for (UInt_64 i = 0; i < varTmpls.Size(); ++i)
|
||||
if (varTmpls[i].GetHashId() == hashId)
|
||||
return &varTmpls[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DbTable::Serialize(const Str_8 &dir, Serializer<UInt_64>& data) const
|
||||
{
|
||||
data.WriteStr(id);
|
||||
data.Write(varTmpls.Size());
|
||||
|
||||
for (UInt_64 i = 0; i < varTmpls.Size(); ++i)
|
||||
varTmpls[i].Serialize(data);
|
||||
|
||||
if (objects.Size())
|
||||
Directory::Create(dir + "/" + id);
|
||||
|
||||
for (UInt_64 i = 0; i < objects.Size(); ++i)
|
||||
objects[i].Save();
|
||||
}
|
||||
|
||||
void DbTable::Deserialize(const Str_8 &dir, Serializer<UInt_64>& data)
|
||||
{
|
||||
id = data.ReadStr<Char_8, UInt_64>();
|
||||
hashId = id.Hash_64();
|
||||
|
||||
varTmpls.Resize(data.Read<UInt_64>());
|
||||
|
||||
for (UInt_64 i = 0; i < varTmpls.Size(); ++i)
|
||||
varTmpls[i].Deserialize(data);
|
||||
|
||||
Array<Str_8> files = Directory::GetAllFiles(dir + "/" + id);
|
||||
for (UInt_64 i = 0; i < files.Size(); ++i)
|
||||
{
|
||||
if (File::ParseExt_8(files[i]) != "eho")
|
||||
continue;
|
||||
|
||||
objects.Push(DbObject(File::ParseName_8(files[i]).ToDecimal<UInt_64>()));
|
||||
objects[objects.End()].parent = this;
|
||||
}
|
||||
}
|
||||
}
|
102
src/db/DbVar.cpp
Normal file
102
src/db/DbVar.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "ehs/db/DbVar.h"
|
||||
#include "ehs/Util.h"
|
||||
#include "ehs/db/DbVarTmpl.h"
|
||||
#include "ehs/db/DbObject.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
DbVar::~DbVar()
|
||||
{
|
||||
delete[] value;
|
||||
}
|
||||
|
||||
DbVar::DbVar()
|
||||
: hashId(0), parent(nullptr), value(nullptr), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
DbVar::DbVar(const UInt_64 hashId, const DbVarTmpl * const master)
|
||||
: hashId(hashId), parent(nullptr), value(new Byte[master->GetSize()]), size(master->GetSize())
|
||||
{
|
||||
Util::Copy(value, &(*master)[0], size);
|
||||
}
|
||||
|
||||
DbVar::DbVar(DbVar &&var) noexcept
|
||||
: hashId(var.hashId), parent(var.parent), value(var.value), size(var.size)
|
||||
{
|
||||
var.hashId = 0;
|
||||
var.parent = nullptr;
|
||||
var.value = nullptr;
|
||||
var.size = 0;
|
||||
}
|
||||
|
||||
DbVar::DbVar(const DbVar &var)
|
||||
: hashId(0), parent(nullptr), value(nullptr), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
DbVar &DbVar::operator=(DbVar &&var) noexcept
|
||||
{
|
||||
if (this == &var)
|
||||
return *this;
|
||||
|
||||
delete[] value;
|
||||
|
||||
hashId = var.hashId;
|
||||
parent = var.parent;
|
||||
value = var.value;
|
||||
size = var.size;
|
||||
|
||||
var.hashId = 0;
|
||||
var.value = nullptr;
|
||||
var.size = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DbVar &DbVar::operator=(const DbVar &var)
|
||||
{
|
||||
if (this == &var)
|
||||
return *this;
|
||||
|
||||
delete[] value;
|
||||
|
||||
hashId = 0;
|
||||
parent = nullptr;
|
||||
value = nullptr;
|
||||
size = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DbVar::operator Byte *() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
UInt_64 DbVar::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
UInt_64 DbVar::GetSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
void DbVar::Serialize(Serializer<UInt_64> &data) const
|
||||
{
|
||||
data.Write(hashId);
|
||||
data.WriteArray(value, size);
|
||||
}
|
||||
|
||||
void DbVar::Deserialize(Serializer<UInt_64> &data)
|
||||
{
|
||||
hashId = data.Read<UInt_64>();
|
||||
|
||||
size = 0;
|
||||
data.ReadArray(value, &size);
|
||||
value = new Byte[size];
|
||||
data.ReadArray(value, &size);
|
||||
}
|
||||
}
|
120
src/db/DbVarTmpl.cpp
Normal file
120
src/db/DbVarTmpl.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "ehs/db/DbVarTmpl.h"
|
||||
#include "ehs/db/DbVar.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
DbVarTmpl::~DbVarTmpl()
|
||||
{
|
||||
delete[] def;
|
||||
}
|
||||
|
||||
DbVarTmpl::DbVarTmpl()
|
||||
: hashId(0), def(nullptr), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
DbVarTmpl::DbVarTmpl(Str_8 id)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), def(nullptr), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
DbVarTmpl::DbVarTmpl(DbVarTmpl &&varTmpl) noexcept
|
||||
: hashId(varTmpl.hashId), id((Str_8&&)varTmpl.id), def(varTmpl.def), size(varTmpl.size)
|
||||
{
|
||||
varTmpl.hashId = 0;
|
||||
varTmpl.def = nullptr;
|
||||
varTmpl.size = 0;
|
||||
}
|
||||
|
||||
DbVarTmpl::DbVarTmpl(const DbVarTmpl &varTmpl)
|
||||
: hashId(varTmpl.hashId), id(varTmpl.id), def(varTmpl.def), size(varTmpl.size)
|
||||
{
|
||||
}
|
||||
|
||||
DbVarTmpl &DbVarTmpl::operator=(DbVarTmpl &&varTmpl) noexcept
|
||||
{
|
||||
if (this == &varTmpl)
|
||||
return *this;
|
||||
|
||||
delete[] def;
|
||||
|
||||
hashId = varTmpl.hashId;
|
||||
id = (Str_8&&)varTmpl.id;
|
||||
def = varTmpl.def;
|
||||
size = varTmpl.size;
|
||||
|
||||
varTmpl.hashId = 0;
|
||||
varTmpl.def = nullptr;
|
||||
varTmpl.size = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DbVarTmpl& DbVarTmpl::operator=(const DbVarTmpl& varTmpl)
|
||||
{
|
||||
if (this == &varTmpl)
|
||||
return *this;
|
||||
|
||||
delete[] def;
|
||||
|
||||
hashId = varTmpl.hashId;
|
||||
id = varTmpl.id;
|
||||
def = new Byte[varTmpl.size];
|
||||
size = varTmpl.size;
|
||||
|
||||
Util::Copy(def, varTmpl.def, varTmpl.size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DbVarTmpl::operator Byte *() const
|
||||
{
|
||||
return def;
|
||||
}
|
||||
|
||||
UInt_64 DbVarTmpl::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void DbVarTmpl::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = (Str_8&&)newId;
|
||||
}
|
||||
|
||||
Str_8 DbVarTmpl::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
UInt_64 DbVarTmpl::GetSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
void DbVarTmpl::Serialize(Serializer<UInt_64> &data) const
|
||||
{
|
||||
data.WriteStr(id);
|
||||
data.WriteArray(def, size);
|
||||
}
|
||||
|
||||
void DbVarTmpl::Deserialize(Serializer<UInt_64> &data)
|
||||
{
|
||||
id = data.ReadStr<Char_8, UInt_64>();
|
||||
hashId = id.Hash_64();
|
||||
|
||||
size = 0;
|
||||
data.ReadArray(def, &size);
|
||||
delete[] def;
|
||||
|
||||
if (!size)
|
||||
{
|
||||
def = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
def = new Byte[size];
|
||||
data.ReadArray(def, &size);
|
||||
}
|
||||
}
|
23
src/io/BaseDirectory.cpp
Normal file
23
src/io/BaseDirectory.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "ehs/io/BaseDirectory.h"
|
||||
|
||||
#include "ehs/Log.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Array<Str_8> BaseDirectory::GetAllFiles(const Str_8 &dir)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The feature is not supported for this operating system.");
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void BaseDirectory::CreateRecursive(Str_8 dir)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The feature is not supported for this operating system.");
|
||||
}
|
||||
|
||||
void BaseDirectory::Create(const Str_8 &dir)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The feature is not supported for this operating system.");
|
||||
}
|
||||
}
|
@@ -52,7 +52,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&((Byte*)str)[total], size - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(size) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&str.ToBytes()[total], str.Size(true) - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(str.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&((Byte*)str)[total], size - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(size) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&str.ToBytes()[total], str.Size(true) - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(str.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&((Byte*)str)[total], size - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(size) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -162,7 +162,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&str.ToBytes()[total], str.Size(true) - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(str.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -184,7 +184,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&vec[total], vec.Size() - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(vec.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -206,7 +206,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&arr[total], arr.Size() - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(arr.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&ser[total], ser.Size() - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(ser.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
@@ -250,7 +250,7 @@ namespace ehs
|
||||
UInt_64 written = Write(&ser[total], ser.Size() - total);
|
||||
if (!written)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write all data (" + Str_8::FromNum(total) + "/" +
|
||||
Str_8::FromNum(ser.Size()) + ").");
|
||||
break;
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ namespace ehs
|
||||
nullptr);
|
||||
if (hdl == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to create handle at COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to create handle at COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ehs
|
||||
|
||||
if (!GetCommState(hdl, &dcb))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve COM" + Str_8::FromNum(port) + " state with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve COM" + Str_8::FromNum(port) + " state with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
return;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace ehs
|
||||
|
||||
if (!SetCommState(hdl, &dcb))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to set COM" + Str_8::FromNum(port) + " state with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to set COM" + Str_8::FromNum(port) + " state with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
return;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ namespace ehs
|
||||
if (hdl)
|
||||
{
|
||||
if (!CloseHandle(hdl))
|
||||
EHS_LOG_INT("Error", 0, "Failed to close COM" + Str_8::FromNum(port) + " handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close COM" + Str_8::FromNum(port) + " handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
hdl = nullptr;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ namespace ehs
|
||||
|
||||
if (!WaitCommEvent(hdl, (DWORD*)&event, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to wait for COM" + Str_8::FromNum(port) + " event with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to wait for COM" + Str_8::FromNum(port) + " event with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ehs
|
||||
|
||||
if (!TransmitCommChar(hdl, data))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to transmit character to COM" + Str_8::FromNum(port) + " with error #" +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to transmit character to COM" + Str_8::FromNum(port) + " with error #" +
|
||||
Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
}
|
||||
@@ -103,7 +103,7 @@ namespace ehs
|
||||
|
||||
if (!WriteFile(hdl, (void*)data, (DWORD)size, (DWORD*)&sent, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to receive data from COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data from COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace ehs
|
||||
|
||||
if (!ReadFile(hdl, (void*)data, (DWORD)size, (DWORD*)&received, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to receive data from COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data from COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace ehs
|
||||
{
|
||||
if (!FlushFileBuffers(hdl))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to flush data for COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to flush data for COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
UnInitialize();
|
||||
}
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ namespace ehs
|
||||
{
|
||||
//DWORD code = WaitForSingleObject(hdlIn, 15000);
|
||||
//if (code == WAIT_FAILED || code == WAIT_TIMEOUT || code == WAIT_ABANDONED)
|
||||
// EHS_LOG_INT("Error", 0, "Failed to wait for console input.");
|
||||
// EHS_LOG_INT(LogType::ERR, 0, "Failed to wait for console input.");
|
||||
|
||||
isConsole = true;
|
||||
}
|
||||
@@ -63,10 +63,10 @@ namespace ehs
|
||||
hdlOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
if (WaitForSingleObject(hdlIn, EHS_INFINITE) == WAIT_FAILED)
|
||||
EHS_LOG_INT("Error", 2, "Failed to wait for console input.");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to wait for console input.");
|
||||
|
||||
//if (!SetConsoleActiveScreenBuffer(hdlOut))
|
||||
// EHS_LOG_INT("Error", 3, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
// EHS_LOG_INT(LogType::ERR, 3, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
isConsole = true;
|
||||
#endif
|
||||
@@ -78,15 +78,15 @@ namespace ehs
|
||||
{
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
if (!FreeConsole())
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
#elif defined(EHS_OS_LINUX)
|
||||
int code = close(hdlOut);
|
||||
if (code == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to free the console output with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to free the console output with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
code = close(hdlIn);
|
||||
if (code == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to free the console input with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to free the console input with error #" + Str_8::FromNum(errno) + ".");
|
||||
#endif
|
||||
|
||||
hdlOut = 0;
|
||||
@@ -118,7 +118,7 @@ namespace ehs
|
||||
{
|
||||
DWORD written = 0;
|
||||
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
offset += written;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ namespace ehs
|
||||
{
|
||||
DWORD written = 0;
|
||||
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
offset += written;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, result, result.Size(true));
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -178,7 +178,7 @@ namespace ehs
|
||||
{
|
||||
DWORD written = 0;
|
||||
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
offset += written;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ namespace ehs
|
||||
{
|
||||
DWORD written = 0;
|
||||
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
offset += written;
|
||||
}
|
||||
@@ -212,7 +212,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, result, result.Size(true));
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -236,7 +236,7 @@ namespace ehs
|
||||
{
|
||||
DWORD written = 0;
|
||||
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
offset += written;
|
||||
}
|
||||
@@ -254,7 +254,7 @@ namespace ehs
|
||||
{
|
||||
DWORD written = 0;
|
||||
if (!WriteFile(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
offset += written;
|
||||
}
|
||||
@@ -270,7 +270,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, result, result.Size());
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -299,7 +299,7 @@ namespace ehs
|
||||
|
||||
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return U"";
|
||||
}
|
||||
@@ -329,7 +329,7 @@ namespace ehs
|
||||
|
||||
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return U"";
|
||||
}
|
||||
@@ -355,7 +355,7 @@ namespace ehs
|
||||
read = ::read(hdlIn, input, bufferSize);
|
||||
if (read == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return result;
|
||||
}
|
||||
result.Push(input, read);
|
||||
@@ -388,7 +388,7 @@ namespace ehs
|
||||
|
||||
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return L"";
|
||||
}
|
||||
@@ -418,7 +418,7 @@ namespace ehs
|
||||
|
||||
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return L"";
|
||||
}
|
||||
@@ -444,7 +444,7 @@ namespace ehs
|
||||
read = ::read(hdlIn, input, bufferSize);
|
||||
if (read == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return result;
|
||||
}
|
||||
result.Push(input, read);
|
||||
@@ -477,7 +477,7 @@ namespace ehs
|
||||
|
||||
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -507,7 +507,7 @@ namespace ehs
|
||||
|
||||
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -533,7 +533,7 @@ namespace ehs
|
||||
read = ::read(hdlIn, input, bufferSize);
|
||||
if (read == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return result;
|
||||
}
|
||||
result.Push(input, read);
|
||||
@@ -573,7 +573,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, code, sizeof(code));
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to clear console with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to clear console with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -586,7 +586,7 @@ namespace ehs
|
||||
{
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
if (!SetConsoleTitleW(UTF::To_16(title)))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set console title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
#elif defined(EHS_OS_LINUX)
|
||||
Str_32 code = U"\033]0;" + title + U"\007";
|
||||
UInt_64 offset = 0;
|
||||
@@ -594,7 +594,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, code, code.Size(true));
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -607,7 +607,7 @@ namespace ehs
|
||||
{
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
if (!SetConsoleTitleW(title))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
#elif defined(EHS_OS_LINUX)
|
||||
Str_16 code = L"\033]0;" + title + L"\007";
|
||||
UInt_64 offset = 0;
|
||||
@@ -615,7 +615,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, code, code.Size(true));
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -628,7 +628,7 @@ namespace ehs
|
||||
{
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
if (!SetConsoleTitleW(UTF::To_16(title)))
|
||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
#elif defined(EHS_OS_LINUX)
|
||||
Str_8 code = "\033]0;" + title + "\007";
|
||||
UInt_64 offset = 0;
|
||||
@@ -636,7 +636,7 @@ namespace ehs
|
||||
ssize_t written = write(hdlOut, code, code.Size());
|
||||
if (written == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
offset += written;
|
||||
@@ -788,7 +788,7 @@ namespace ehs
|
||||
#if defined(EHS_OS_WINDOWS)
|
||||
void* hdl = FindWindowW(nullptr, GetTitle_16());
|
||||
if (hdl == nullptr)
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve native handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve native handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return hdl;
|
||||
#else
|
||||
|
83
src/io/Directory_LNX.cpp
Normal file
83
src/io/Directory_LNX.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "ehs/io/Directory_LNX.h"
|
||||
#include "ehs/Log.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <cerrno>
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Array<Str_8> Directory::GetAllFiles(const Str_8& dir)
|
||||
{
|
||||
Array<Str_8> result;
|
||||
|
||||
if (!dir.Size())
|
||||
{
|
||||
EHS_LOG_INT(LogType::WARN, 1, "The given directory was empty.");
|
||||
return result;
|
||||
}
|
||||
|
||||
DIR* hdl = opendir(dir);
|
||||
if (!hdl)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to open directory, \"" + dir + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
dirent* entry;
|
||||
while ((entry = readdir(hdl)))
|
||||
if (entry->d_type == DT_REG)
|
||||
result.Push(entry->d_name);
|
||||
|
||||
if (closedir(hdl) == -1)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to close directory, \"" + dir + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Directory::CreateRecursive(Str_8 dir)
|
||||
{
|
||||
dir = dir.ReplaceAll("\\", "/");
|
||||
|
||||
const Vector<Str_8> dirs = dir.Split("/");
|
||||
|
||||
for (UInt_64 i = 0; i < dirs.Size(); ++i)
|
||||
{
|
||||
const Str_8 final = (Str_8&&)dirs[i];
|
||||
for (UInt_64 x = 0; x < i; ++x)
|
||||
dirs[i] += dirs[x] + "/";
|
||||
|
||||
dirs[i] += final;
|
||||
|
||||
if (mkdir(dirs[i], S_IRWXU | S_IRWXG | S_IRWXO) == -1)
|
||||
{
|
||||
if (const SInt_32 code = errno; code != EEXIST)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to create directory, \"" + dirs[i] + "\" with error #" + Str_8::FromNum(code) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
|
||||
void Directory::Create(const Str_8 &dir)
|
||||
{
|
||||
if (mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO) == -1)
|
||||
{
|
||||
if (const SInt_32 code = errno; code != EEXIST)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to create directory with error #" + Str_8::FromNum(code) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
}
|
87
src/io/Directory_W32.cpp
Normal file
87
src/io/Directory_W32.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "ehs/io/Directory_W32.h"
|
||||
#include "ehs/UTF.h"
|
||||
#include "ehs/Log.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Array<Str_8> GetAllFiles(const Str_8 &dir)
|
||||
{
|
||||
Array<Str_8> result;
|
||||
|
||||
if (!dir.Size())
|
||||
{
|
||||
EHS_LOG_INT(LogType::WARN, 1, "The given directory was empty.");
|
||||
return result;
|
||||
}
|
||||
|
||||
WIN32_FIND_DATAW fData;
|
||||
HANDLE hFind = FindFirstFileW(UTF::To_16(dir) + L"\\*", &fData);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to open directory, \"" + dir + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Str_8 fName = UTF::To_8(fData.cFileName);
|
||||
if (fName == "." || fName == "..")
|
||||
continue;
|
||||
|
||||
result.Push(fName);
|
||||
}
|
||||
while (FindNextFileW(hFind, &fData) != 0);
|
||||
|
||||
if (!FindClose(hFind))
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to close directory, \"" + dir + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CreateRecursive(Str_8 dir)
|
||||
{
|
||||
dir = dir.ReplaceAll("\\", "/");
|
||||
|
||||
const Vector<Str_8> dirs = dir.Split("/");
|
||||
|
||||
for (UInt_64 i = 0; i < dirs.Size(); ++i)
|
||||
{
|
||||
const Str_8 final = (Str_8&&)dirs[i];
|
||||
for (UInt_64 x = 0; x < i; ++x)
|
||||
dirs[i] += dirs[x] + "/";
|
||||
|
||||
dirs[i] += final;
|
||||
|
||||
if (!CreateDirectoryW(UTF::To_16(dirs[i]), nullptr))
|
||||
{
|
||||
if (const DWORD code = GetLastError(); code != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to create directory, \"" + dirs[i] + "\" with error #" + Str_8::FromNum(code) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
|
||||
void Create(const Str_8 &dir)
|
||||
{
|
||||
if (!CreateDirectoryW(UTF::To_16(dir), nullptr))
|
||||
{
|
||||
if (const DWORD code = GetLastError(); code != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to create directory, \"" + dir + "\" with error #" + Str_8::FromNum(code) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
}
|
@@ -83,14 +83,14 @@ namespace ehs
|
||||
hdl = inotify_init();
|
||||
if (hdl < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to initialize inotify.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to initialize inotify.");
|
||||
return;
|
||||
}
|
||||
|
||||
int flags = fcntl(hdl, F_GETFL, 0);
|
||||
if (flags == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve flags with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve flags with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,14 +98,14 @@ namespace ehs
|
||||
|
||||
if (fcntl(hdl, F_SETFL, flags) == -1)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to set flags with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to set flags with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
wd = inotify_add_watch( hdl, filePath, IN_MODIFY | IN_DELETE_SELF | IN_MOVE_SELF | IN_ACCESS);
|
||||
if (wd < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to add watch.");
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to add watch.");
|
||||
close(hdl);
|
||||
hdl = -1;
|
||||
return;
|
||||
@@ -137,7 +137,7 @@ namespace ehs
|
||||
{
|
||||
UInt_8 code = errno;
|
||||
if (code != EWOULDBLOCK)
|
||||
EHS_LOG_INT("Error", 0, "Failed to read with error #" + Str_8::FromNum(code) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to read with error #" + Str_8::FromNum(code) + ".");
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (!CloseHandle(hdl))
|
||||
EHS_LOG_INT("Error", 0, "Failed to close file at file path, \"" + filePath + "\", with error #" + GetLastError() + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close file at file path, \"" + filePath + "\", with error #" + GetLastError() + ".");
|
||||
}
|
||||
|
||||
FileMonitor::FileMonitor()
|
||||
: hdl(nullptr), time{}
|
||||
: hdl(INVALID_HANDLE_VALUE), time{}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace ehs
|
||||
hdl = CreateFileW(UTF::To_16(filePath), GENERIC_READ, FILE_SHARE_READ,
|
||||
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hdl == INVALID_HANDLE_VALUE)
|
||||
EHS_LOG_INT("Error", 0, "Failed to open file at file path, \"" + filePath + "\", with error #" + GetLastError() + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to open file at file path, \"" + filePath + "\", with error #" + GetLastError() + ".");
|
||||
}
|
||||
|
||||
void FileMonitor::Release()
|
||||
@@ -91,9 +91,9 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (!CloseHandle(hdl))
|
||||
EHS_LOG_INT("Error", 0, "Failed to close file at file path, \"" + filePath + "\", with error #" + GetLastError() + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close file at file path, \"" + filePath + "\", with error #" + GetLastError() + ".");
|
||||
|
||||
hdl = nullptr;
|
||||
hdl = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
UInt_8 FileMonitor::Poll()
|
||||
|
@@ -13,10 +13,10 @@ namespace ehs
|
||||
File::~File()
|
||||
{
|
||||
if (map != MAP_FAILED && munmap(map, mapSize) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
if (hdl >= 0 && close(hdl) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
File::File()
|
||||
@@ -64,21 +64,29 @@ namespace ehs
|
||||
hdl = open64(path, linuxMode | linuxDisp, S_IRUSR | S_IWUSR);
|
||||
if (hdl == -1)
|
||||
{
|
||||
SInt_32 code = errno;
|
||||
const SInt_32 code = errno;
|
||||
if (code == EEXIST && (disposition == Disposition::CREATE_PERSISTENT || disposition == Disposition::OPEN_PERSISTENT))
|
||||
{
|
||||
hdl = open64(path, linuxMode, S_IRUSR | S_IWUSR);
|
||||
if (hdl == -1)
|
||||
EHS_LOG_INT("Error", 0, strerror(errno));
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, strerror(errno));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (code == ENOENT)
|
||||
EHS_LOG_INT("Error", 0, "File at filepath, \"" + filePath + "\" not found.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "File at filepath, \"" + filePath + "\" not found.");
|
||||
else
|
||||
EHS_LOG_INT("Error", 0, strerror(code));
|
||||
EHS_LOG_INT(LogType::ERR, 1, strerror(code));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
|
||||
File::File(File&& file) noexcept
|
||||
@@ -137,12 +145,12 @@ namespace ehs
|
||||
void File::Release()
|
||||
{
|
||||
if (IsMapped() && munmap(map, mapSize) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
map = MAP_FAILED;
|
||||
mapSize = 0;
|
||||
|
||||
if (IsValid() && close(hdl) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||
hdl = -1;
|
||||
}
|
||||
|
||||
@@ -178,7 +186,7 @@ namespace ehs
|
||||
map = mmap64(nullptr, size, linuxMode, MAP_SHARED, hdl, (off64_t)offset);
|
||||
if (map == MAP_FAILED)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to map with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to map with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -191,7 +199,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (munmap(map, mapSize) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
map = MAP_FAILED;
|
||||
mapSize = 0;
|
||||
@@ -203,7 +211,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (msync((void*)map, mapSize, MS_SYNC) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to flush view with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to flush view with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
UInt_64 File::Write(const Byte *const data, const UInt_64 size)
|
||||
@@ -214,7 +222,7 @@ namespace ehs
|
||||
SInt_64 written = 0;
|
||||
written = write(hdl, data, size);
|
||||
if (written == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return (UInt_64)written;
|
||||
}
|
||||
@@ -227,7 +235,7 @@ namespace ehs
|
||||
SInt_64 read = 0;
|
||||
read = ::read(hdl, data, (size_t)size);
|
||||
if (read == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return (UInt_64)read;
|
||||
}
|
||||
@@ -238,7 +246,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (lseek64(hdl, (off64_t)index, SEEK_SET) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
void File::SeekBeginning()
|
||||
@@ -247,7 +255,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (lseek64(hdl, 0, SEEK_SET) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
void File::SeekEnd()
|
||||
@@ -256,7 +264,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (lseek64(hdl, 0, SEEK_END) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
void File::Truncate(const UInt_64 size)
|
||||
@@ -265,7 +273,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (ftruncate64(hdl, (off64_t)size) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to truncate with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to truncate with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
UInt_64 File::Size() const
|
||||
@@ -273,7 +281,7 @@ namespace ehs
|
||||
struct stat64 info = {};
|
||||
|
||||
if (fstat64(hdl, &info) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve file size with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve file size with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return info.st_size;
|
||||
}
|
||||
@@ -302,6 +310,6 @@ namespace ehs
|
||||
path = filePath.Sub(0, index);
|
||||
|
||||
if (rename(filePath, path + newName) == -1)
|
||||
EHS_LOG_INT("Error", 0, "Failed to rename file with error #" + Str_8::FromNum(errno) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to rename file with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
}
|
||||
|
@@ -5,13 +5,13 @@ namespace ehs
|
||||
File::~File()
|
||||
{
|
||||
if (view && !UnmapViewOfFile(view))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
if (map != INVALID_HANDLE_VALUE && !CloseHandle(map))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
if (hdl != INVALID_HANDLE_VALUE && !CloseHandle(hdl))
|
||||
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close file handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
File::File()
|
||||
@@ -62,12 +62,14 @@ namespace ehs
|
||||
{
|
||||
DWORD code = GetLastError();
|
||||
if (code == ERROR_FILE_NOT_FOUND)
|
||||
EHS_LOG_INT("Error", 1, "File not found at path, \"" + path + "\".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "File not found at path, \"" + path + "\".");
|
||||
else if (code != ERROR_SUCCESS)
|
||||
EHS_LOG_INT("Error", 2, "Failed to create handle for file, \"" + path + "\", with error #" + Str_8::FromNum(code) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to create handle for file, \"" + path + "\", with error #" + Str_8::FromNum(code) + ".");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
}
|
||||
|
||||
File::File(File&& file) noexcept
|
||||
@@ -132,16 +134,16 @@ namespace ehs
|
||||
void File::Release()
|
||||
{
|
||||
if (view && !UnmapViewOfFile(view))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
view = nullptr;
|
||||
viewSize = 0;
|
||||
|
||||
if (IsMapped() && !CloseHandle(map))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
map = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (IsValid() && !CloseHandle(hdl))
|
||||
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to close file handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
hdl = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@@ -177,7 +179,7 @@ namespace ehs
|
||||
map = CreateFileMappingW(hdl, nullptr, winMode, 0, 0, nullptr);
|
||||
if (!map)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to create map handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to create map handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -197,10 +199,10 @@ namespace ehs
|
||||
view = (Byte*)MapViewOfFile(map, winMode, ((DWORD*)&offset)[1], (DWORD)offset, size);
|
||||
if (!view)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to map view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to map view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
if (!CloseHandle(map))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
map = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@@ -213,12 +215,12 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (!UnmapViewOfFile(view))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
view = nullptr;
|
||||
viewSize = 0;
|
||||
|
||||
if (!CloseHandle(map))
|
||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to unmap with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
map = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@@ -228,7 +230,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (!FlushViewOfFile(view, viewSize))
|
||||
EHS_LOG_INT("Error", 0, "Failed to flush view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to flush view with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
UInt_64 File::Write(const Byte *const data, const UInt_64 size)
|
||||
@@ -239,7 +241,7 @@ namespace ehs
|
||||
SInt_64 written = 0;
|
||||
|
||||
if (!WriteFile(hdl, data, (DWORD)size, (DWORD*)&written, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return (UInt_64)written;
|
||||
}
|
||||
@@ -252,7 +254,7 @@ namespace ehs
|
||||
SInt_64 read = 0;
|
||||
|
||||
if (!ReadFile(hdl, data, (DWORD)size, (DWORD*)&read, nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return (UInt_64)read;
|
||||
}
|
||||
@@ -263,7 +265,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (SetFilePointer(hdl, (LONG)index, (PLONG)&((UInt_32*)&index)[1], FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to seek with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
void File::SeekBeginning()
|
||||
@@ -272,7 +274,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (SetFilePointer(hdl, 0, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to seek with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
void File::SeekEnd()
|
||||
@@ -281,7 +283,7 @@ namespace ehs
|
||||
return;
|
||||
|
||||
if (SetFilePointer(hdl, 0, nullptr, FILE_END) == INVALID_SET_FILE_POINTER)
|
||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to seek with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
void File::Truncate(const UInt_64 size)
|
||||
@@ -292,7 +294,7 @@ namespace ehs
|
||||
Seek(size);
|
||||
|
||||
if (!::SetEndOfFile(hdl))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set end of file with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set end of file with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
SeekBeginning();
|
||||
}
|
||||
@@ -305,7 +307,7 @@ namespace ehs
|
||||
LARGE_INTEGER size = {};
|
||||
|
||||
if (!GetFileSizeEx(hdl, &size))
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve file size with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve file size with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return (UInt_64)size.QuadPart;
|
||||
}
|
||||
@@ -329,7 +331,7 @@ namespace ehs
|
||||
path = filePath.Sub(0, index);
|
||||
|
||||
if (!MoveFileW(filePath, path + newName))
|
||||
EHS_LOG_INT("Error", 0, "Failed to rename file with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to rename file with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
void File::Rename_8(const Str_8& filePath, const Str_8& newName)
|
||||
|
@@ -27,7 +27,7 @@ namespace ehs
|
||||
Version ver = fData.ReadVersion();
|
||||
if (ver != Version(1, 0, 0))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "The Event Horizon Font file, \"" + filePath + "\", must be version 1.0.0, but was version " +
|
||||
EHS_LOG_INT(LogType::ERR, 2, "The Event Horizon Font file, \"" + filePath + "\", must be version 1.0.0, but was version " +
|
||||
Str_8::FromNum(ver.major) + "." + Str_8::FromNum(ver.minor) + "." +
|
||||
Str_8::FromNum(ver.patch) + ".");
|
||||
return;
|
||||
@@ -40,8 +40,9 @@ namespace ehs
|
||||
glyphs[i] = Glyph(fData);
|
||||
|
||||
resolution = fData.ReadVec2<UInt_64>();
|
||||
size = resolution.x * resolution.y;
|
||||
atlas = new Byte[size];
|
||||
atlas = new Byte[resolution.x * resolution.y];
|
||||
size = 0;
|
||||
fData.ReadArray(atlas, &size);
|
||||
fData.ReadArray(atlas, &size);
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ namespace ehs
|
||||
{
|
||||
}
|
||||
|
||||
Glyph::Glyph(Serializer<>& ser)
|
||||
Glyph::Glyph(Serializer<ehs::UInt_64>& ser)
|
||||
: code(ser.Read<Char_32>()), pos(ser.ReadVec2<UInt_64>()), scale(ser.ReadVec2<UInt_64>()),
|
||||
uv(ser.ReadRect<float>()), bearing(ser.ReadVec2<Int_64>()), advance(ser.ReadVec2<UInt_64>())
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ namespace ehs
|
||||
Str_8 riffId = data.ReadStr<Char_8, UInt_64>(4);
|
||||
if (riffId != "RIFF")
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "File at file path, \"" + filePath + "\", is not a valid RIFF file.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "File at file path, \"" + filePath + "\", is not a valid RIFF file.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ehs
|
||||
Str_8 riffId = data.ReadStr<Char_8, UInt_64>(4);
|
||||
if (riffId != "RIFF")
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Data is not in RIFF format.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Data is not in RIFF format.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
95
src/io/UsbBase.cpp
Normal file
95
src/io/UsbBase.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "ehs/io/UsbBase.h"
|
||||
#include "ehs/Util.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
UsbBase::UsbBase()
|
||||
: bus(0), address(0)
|
||||
{
|
||||
}
|
||||
|
||||
UsbBase::UsbBase(const UInt_32 bus, const UInt_32 address)
|
||||
: bus(bus), address(address)
|
||||
{
|
||||
}
|
||||
|
||||
UsbBase::UsbBase(UsbBase&& usb) noexcept
|
||||
: bus(usb.bus), address(usb.address)
|
||||
{
|
||||
usb.bus = 0;
|
||||
usb.address = 0;
|
||||
}
|
||||
|
||||
UsbBase::UsbBase(const UsbBase& usb)
|
||||
: bus(usb.bus), address(usb.address)
|
||||
{
|
||||
}
|
||||
|
||||
UsbBase& UsbBase::operator=(UsbBase&& usb) noexcept
|
||||
{
|
||||
if (this == &usb)
|
||||
return *this;
|
||||
|
||||
bus = usb.bus;
|
||||
address = usb.address;
|
||||
|
||||
usb.bus = 0;
|
||||
usb.address = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UsbBase& UsbBase::operator=(const UsbBase& usb)
|
||||
{
|
||||
if (this == &usb)
|
||||
return *this;
|
||||
|
||||
bus = usb.bus;
|
||||
address = usb.address;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void UsbBase::BulkSend(const Byte* const data, const Size size)
|
||||
{
|
||||
Size out = 0;
|
||||
while (out < size)
|
||||
out = Send(&data[out], size);
|
||||
}
|
||||
|
||||
void UsbBase::BulkReceive(Byte** data, Size* size)
|
||||
{
|
||||
Byte *result = nullptr;
|
||||
Size total = 0;
|
||||
Size in;
|
||||
do
|
||||
{
|
||||
Byte *resize = new Byte[(total + *size) / *size];
|
||||
Util::Copy(resize, result, total);
|
||||
|
||||
in = Receive(&resize[total], *size);
|
||||
total += in;
|
||||
|
||||
delete[] result;
|
||||
result = resize;
|
||||
}
|
||||
while (in);
|
||||
|
||||
*size = total;
|
||||
}
|
||||
|
||||
UInt_32 UsbBase::GetBus() const
|
||||
{
|
||||
return bus;
|
||||
}
|
||||
|
||||
UInt_32 UsbBase::GetAddress() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
bool UsbBase::IsValid() const
|
||||
{
|
||||
return bus && address;
|
||||
}
|
||||
}
|
106
src/io/Usb_LNX.cpp
Normal file
106
src/io/Usb_LNX.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "ehs/io/Usb_LNX.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Usb::~Usb()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Usb::Usb()
|
||||
: hdl(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Usb::Usb(const UInt_32 bus, const UInt_32 address)
|
||||
: UsbBase(bus, address), hdl(-1)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Usb::Usb(Usb&& usb) noexcept
|
||||
: UsbBase((UsbBase&&)usb), hdl(usb.hdl)
|
||||
{
|
||||
usb.hdl = -1;
|
||||
}
|
||||
|
||||
Usb::Usb(const Usb& usb)
|
||||
: UsbBase(usb), hdl(-1)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Usb& Usb::operator=(Usb&& usb) noexcept
|
||||
{
|
||||
if (this == &usb)
|
||||
return *this;
|
||||
|
||||
UsbBase::operator=((UsbBase&&)usb);
|
||||
|
||||
hdl = usb.hdl;
|
||||
|
||||
usb.hdl = -1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Usb& Usb::operator=(const Usb& usb)
|
||||
{
|
||||
if (this == &usb)
|
||||
return *this;
|
||||
|
||||
UsbBase::operator=(usb);
|
||||
|
||||
hdl = -1;
|
||||
|
||||
Initialize();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Usb::Initialize()
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Cannot initialize with an invalid object.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsInitialized())
|
||||
{
|
||||
EHS_LOG_INT(LogType::WARN, 1, "Object is already initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
hdl = open("/dev/bus/usb/" + Str_8::FromNum(GetBus()) + "/" + Str_8::FromNum(GetAddress()), O_RDWR);
|
||||
if (hdl == -1)
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to connect to USB device.");
|
||||
}
|
||||
|
||||
void Usb::Release()
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Cannot release with an invalid object.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsInitialized())
|
||||
{
|
||||
EHS_LOG_INT(LogType::WARN, 1, "Object is already released.");
|
||||
return;
|
||||
}
|
||||
|
||||
close(hdl);
|
||||
|
||||
hdl = -1;
|
||||
}
|
||||
|
||||
bool Usb::IsInitialized() const
|
||||
{
|
||||
return hdl != -1;
|
||||
}
|
||||
}
|
@@ -95,7 +95,7 @@ namespace ehs
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Getting raw input returned incorrect size.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Getting raw input returned incorrect size.");
|
||||
delete[] data;
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
@@ -108,12 +108,13 @@ namespace ehs
|
||||
if (!keyboard)
|
||||
{
|
||||
UInt_32 bufferSize;
|
||||
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, NULL, &bufferSize);
|
||||
GetRawInputDeviceInfoW(raw->header.hDevice, RIDI_DEVICENAME, nullptr, &bufferSize);
|
||||
|
||||
Char_16* deviceName = new Char_16[bufferSize];
|
||||
|
||||
if (GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, deviceName, &bufferSize) < 0)
|
||||
if (GetRawInputDeviceInfoW(raw->header.hDevice, RIDI_DEVICENAME, deviceName, &bufferSize) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve device name.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve device name.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -134,12 +135,13 @@ namespace ehs
|
||||
if (!mouse)
|
||||
{
|
||||
UInt_32 bufferSize;
|
||||
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, nullptr, &bufferSize);
|
||||
GetRawInputDeviceInfoW(raw->header.hDevice, RIDI_DEVICENAME, nullptr, &bufferSize);
|
||||
|
||||
Char_16* deviceName = new Char_16[bufferSize];
|
||||
|
||||
if (GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, deviceName, &bufferSize) < 0)
|
||||
if (GetRawInputDeviceInfoW(raw->header.hDevice, RIDI_DEVICENAME, deviceName, &bufferSize) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve device name.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve device name.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -202,7 +204,7 @@ namespace ehs
|
||||
if (win->cursorConstrained)
|
||||
{
|
||||
if (!ClipCursor(nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed to free cursor after losing focus with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to free cursor after losing focus with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
win->ih.ResetAllStates();
|
||||
@@ -220,7 +222,7 @@ namespace ehs
|
||||
|
||||
if (!GetClientRect(win->GetHdl(), &client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve client scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve client scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -228,7 +230,7 @@ namespace ehs
|
||||
|
||||
if (!ClientToScreen(win->GetHdl(), &pos))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve client's absolute position with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve client's absolute position with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -239,7 +241,7 @@ namespace ehs
|
||||
|
||||
if (!ClientToScreen(win->GetHdl(), &scale))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve client's absolute scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve client's absolute scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -248,7 +250,7 @@ namespace ehs
|
||||
|
||||
if (!ClipCursor(&client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to confine cursor with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to confine cursor with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
@@ -347,7 +349,7 @@ namespace ehs
|
||||
wcex.lpszClassName = title;
|
||||
|
||||
if (!RegisterClassExW(&wcex))
|
||||
EHS_LOG_INT("Error", 0, "Failed to register window.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to register window.");
|
||||
|
||||
hdl = CreateWindowExW(
|
||||
0,
|
||||
@@ -362,7 +364,7 @@ namespace ehs
|
||||
|
||||
if (!hdl)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to create window.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to create window.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -391,7 +393,7 @@ namespace ehs
|
||||
|
||||
if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == false)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to register raw input devices.");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to register raw input devices.");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -434,7 +436,7 @@ namespace ehs
|
||||
void Window::SetTitle_32(const Str_32& title)
|
||||
{
|
||||
if (!SetWindowTextW(hdl, UTF::To_16(title)))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
Str_32 Window::GetTitle_32() const
|
||||
@@ -445,7 +447,7 @@ namespace ehs
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -459,7 +461,7 @@ namespace ehs
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -471,7 +473,7 @@ namespace ehs
|
||||
void Window::SetTitle_16(const Str_16& title)
|
||||
{
|
||||
if (!SetWindowTextW(hdl, title))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
Str_16 Window::GetTitle_16() const
|
||||
@@ -482,7 +484,7 @@ namespace ehs
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -496,7 +498,7 @@ namespace ehs
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -508,7 +510,7 @@ namespace ehs
|
||||
void Window::SetTitle_8(const Str_8& title)
|
||||
{
|
||||
if (!SetWindowTextW(hdl, UTF::To_16(title)))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
Str_8 Window::GetTitle_8() const
|
||||
@@ -519,7 +521,7 @@ namespace ehs
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -533,7 +535,7 @@ namespace ehs
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -547,7 +549,7 @@ namespace ehs
|
||||
Handle icon = LoadImageW(nullptr, UTF::To_16(filePath), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||
if (!icon)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to load icon at file path, \"" + filePath + "\" with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to load icon at file path, \"" + filePath + "\" with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -634,7 +636,7 @@ namespace ehs
|
||||
RECT rect = {};
|
||||
|
||||
if (!GetClientRect(hdl, &rect))
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve client size with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve client size with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return {(UInt_32)rect.right, (UInt_32)rect.bottom};
|
||||
}
|
||||
@@ -677,7 +679,7 @@ namespace ehs
|
||||
|
||||
if (!GetClientRect(GetHdl(), &client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve client scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve client scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -685,7 +687,7 @@ namespace ehs
|
||||
|
||||
if (!ClientToScreen(GetHdl(), &pos))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve client's absolute position with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve client's absolute position with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -696,7 +698,7 @@ namespace ehs
|
||||
|
||||
if (!ClientToScreen(GetHdl(), &scale))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve client's absolute scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve client's absolute scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -705,7 +707,7 @@ namespace ehs
|
||||
|
||||
if (!ClipCursor(&client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to confine cursor with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to confine cursor with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,20 @@
|
||||
#include "io/Window_Way.h"
|
||||
#include "ehs/io/Window_Way.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "ehs/io/Console.h"
|
||||
#include "ehs/io/xdg-shell-client-protocol.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
void Window::SurfaceConfigure(void* data, xdg_surface* xdg_surface, UInt_32 serial)
|
||||
void Window::SurfaceConfigEvent(void* data, xdg_surface* xdg_surface, UInt_32 serial)
|
||||
{
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
|
||||
//Window* win = (Window *)data;
|
||||
|
||||
//wl_surface_commit(win->wlSurface);
|
||||
}
|
||||
|
||||
void Window::ShellPing(void* data, xdg_wm_base* shell, UInt_32 serial)
|
||||
@@ -14,43 +24,162 @@ namespace ehs
|
||||
|
||||
void Window::RegistryHandler(void* data, wl_registry* registry, UInt_32 id, const char* interface, UInt_32 version)
|
||||
{
|
||||
Serializer<UInt_64>* ser = (Serializer<UInt_64>*)data;
|
||||
Window *win = (Window *)data;
|
||||
|
||||
if (Str_8::Cmp(interface, "wl_compositor"))
|
||||
{
|
||||
ser->SetOffset(0);
|
||||
wl_compositor** comp = ser->Read<wl_compositor**>();
|
||||
*comp = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
||||
}
|
||||
|
||||
if (Str_8::Cmp(interface, "xdg_wm_base"))
|
||||
{
|
||||
ser->SetOffset(sizeof(void*));
|
||||
xdg_wm_base** base = ser->Read<xdg_wm_base**>();
|
||||
*base = (xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
|
||||
}
|
||||
if (Str_8::Cmp(interface, wl_compositor_interface.name))
|
||||
win->compositor = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
||||
else if (Str_8::Cmp(interface, xdg_wm_base_interface.name))
|
||||
win->xdgShell = (xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
|
||||
else if (Str_8::Cmp(interface, zxdg_decoration_manager_v1_interface.name))
|
||||
win->decManager = (zxdg_decoration_manager_v1*)wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1);
|
||||
else if (Str_8::Cmp(interface, wl_seat_interface.name))
|
||||
win->seat = (wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1);
|
||||
}
|
||||
|
||||
void Window::RegistryRemoved(void* data, wl_registry* registry, UInt_32 id)
|
||||
{
|
||||
}
|
||||
|
||||
void Window::ResizeEvent(void *data, struct xdg_toplevel *xdg_toplevel, Int_32 width, Int_32 height, wl_array *states)
|
||||
{
|
||||
if (!width && !height)
|
||||
return;
|
||||
|
||||
Window *win = (Window *)data;
|
||||
|
||||
win->scale = {(UInt_32)width, (UInt_32)height};
|
||||
}
|
||||
|
||||
void Window::CloseEvent(void *data, xdg_toplevel *xdg_toplevel)
|
||||
{
|
||||
Window *win = (Window *)data;
|
||||
win->Close();
|
||||
}
|
||||
|
||||
void Window::SeatCapabilitiesEvent(void *data, wl_seat *seat, UInt_32 capabilities)
|
||||
{
|
||||
Window *win = (Window *)data;
|
||||
|
||||
if (capabilities & WL_SEAT_CAPABILITY_POINTER)
|
||||
{
|
||||
win->pointer = wl_seat_get_pointer(seat);
|
||||
|
||||
static const wl_pointer_listener pointer_listener = {
|
||||
.motion = PointerMotionEvent
|
||||
};
|
||||
|
||||
wl_pointer_add_listener(win->pointer, &pointer_listener, win);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::PointerMotionEvent(void *data, wl_pointer *pointer, UInt_32 time, wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
EHS_LOG_INT(LogType::INFO, 0, "Pointer Pos: <" + Str_8::FromNum(wl_fixed_to_double(sx)) + ", " + Str_8::FromNum(wl_fixed_to_double(sy)) + ">");
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
zxdg_toplevel_decoration_v1_destroy(dec);
|
||||
zxdg_decoration_manager_v1_destroy(decManager);
|
||||
xdg_toplevel_destroy(xdgToplevel);
|
||||
xdg_surface_destroy(xdgSurface);
|
||||
xdg_wm_base_destroy(xdgShell);
|
||||
wl_surface_destroy(surface);
|
||||
wl_surface_destroy(wlSurface);
|
||||
wl_compositor_destroy(compositor);
|
||||
wl_registry_destroy(registry);
|
||||
wl_display_disconnect(display);
|
||||
}
|
||||
|
||||
Window::Window()
|
||||
: display(nullptr), registry(nullptr), compositor(nullptr) , surface(nullptr)
|
||||
: display(nullptr), registry(nullptr), compositor(nullptr), wlSurface(nullptr), xdgShell(nullptr),
|
||||
xdgSurface(nullptr), xdgToplevel(nullptr), decManager(nullptr), dec(nullptr), seat(nullptr), pointer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Window::Window(Window &&win) noexcept
|
||||
: BaseWindow(win), display(win.display), registry(win.registry), compositor(win.compositor),
|
||||
wlSurface(win.wlSurface), xdgShell(win.xdgShell), xdgSurface(win.xdgSurface), xdgToplevel(win.xdgToplevel),
|
||||
decManager(win.decManager), dec(win.dec), seat(win.seat), pointer(win.pointer)
|
||||
{
|
||||
win.display = nullptr;
|
||||
win.registry = nullptr;
|
||||
win.compositor = nullptr;
|
||||
win.wlSurface = nullptr;
|
||||
win.xdgShell = nullptr;
|
||||
win.xdgSurface = nullptr;
|
||||
win.xdgToplevel = nullptr;
|
||||
win.decManager = nullptr;
|
||||
win.dec = nullptr;
|
||||
win.seat = nullptr;
|
||||
win.pointer = nullptr;
|
||||
}
|
||||
|
||||
Window::Window(const Window &win)
|
||||
: BaseWindow(win), display(nullptr), registry(nullptr), compositor(nullptr), wlSurface(nullptr),
|
||||
xdgShell(nullptr), xdgSurface(nullptr), xdgToplevel(nullptr), decManager(nullptr), dec(nullptr), seat(nullptr),
|
||||
pointer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Window & Window::operator=(Window &&win) noexcept
|
||||
{
|
||||
if (this == &win)
|
||||
return *this;
|
||||
|
||||
BaseWindow::operator=(win);
|
||||
|
||||
display = win.display;
|
||||
registry = win.registry;
|
||||
compositor = win.compositor;
|
||||
wlSurface = win.wlSurface;
|
||||
xdgShell = win.xdgShell;
|
||||
xdgSurface = win.xdgSurface;
|
||||
xdgToplevel = win.xdgToplevel;
|
||||
decManager = win.decManager;
|
||||
dec = win.dec;
|
||||
seat = win.seat;
|
||||
pointer = win.pointer;
|
||||
|
||||
win.display = nullptr;
|
||||
win.registry = nullptr;
|
||||
win.compositor = nullptr;
|
||||
win.wlSurface = nullptr;
|
||||
win.xdgShell = nullptr;
|
||||
win.xdgSurface = nullptr;
|
||||
win.xdgToplevel = nullptr;
|
||||
win.decManager = nullptr;
|
||||
win.dec = nullptr;
|
||||
win.seat = nullptr;
|
||||
win.pointer = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Window & Window::operator=(const Window &win)
|
||||
{
|
||||
if (this == &win)
|
||||
return *this;
|
||||
|
||||
BaseWindow::operator=(win);
|
||||
|
||||
display = nullptr;
|
||||
registry = nullptr;
|
||||
compositor = nullptr;
|
||||
wlSurface = nullptr;
|
||||
xdgShell = nullptr;
|
||||
xdgSurface = nullptr;
|
||||
xdgToplevel = nullptr;
|
||||
decManager = nullptr;
|
||||
dec = nullptr;
|
||||
seat = nullptr;
|
||||
pointer = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Window::Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
||||
{
|
||||
Create_8(UTF::To_8(title), pos, scale);
|
||||
@@ -63,54 +192,95 @@ namespace ehs
|
||||
|
||||
void Window::Create_8(const Str_8& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
||||
{
|
||||
if (created)
|
||||
return;
|
||||
|
||||
display = wl_display_connect(nullptr);
|
||||
if (!display)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to connect to display server.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to connect to display server.");
|
||||
return;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> data(Endianness::LE);
|
||||
data.Write(&compositor);
|
||||
data.Write(&xdgShell);
|
||||
|
||||
static constexpr wl_registry_listener registry_listener = {
|
||||
RegistryHandler,
|
||||
RegistryRemoved
|
||||
.global = RegistryHandler,
|
||||
.global_remove = RegistryRemoved
|
||||
};
|
||||
|
||||
registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, &data);
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
|
||||
wl_display_dispatch(display);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
if (!compositor || !xdgShell)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Can't find required interfaces.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Can't find required interfaces.");
|
||||
return;
|
||||
}
|
||||
|
||||
static constexpr xdg_wm_base_listener xdg_shell_listener = {ShellPing};
|
||||
static constexpr xdg_wm_base_listener xdg_shell_listener = {
|
||||
.ping = ShellPing
|
||||
};
|
||||
|
||||
xdg_wm_base_add_listener(xdgShell, &xdg_shell_listener, nullptr);
|
||||
|
||||
surface = wl_compositor_create_surface(compositor);
|
||||
if (!surface)
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
wlSurface = wl_compositor_create_surface(compositor);
|
||||
if (!wlSurface)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Can't create surface.");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Can't create surface.");
|
||||
return;
|
||||
}
|
||||
|
||||
xdgSurface = xdg_wm_base_get_xdg_surface(xdgShell, surface);
|
||||
xdgSurface = xdg_wm_base_get_xdg_surface(xdgShell, wlSurface);
|
||||
|
||||
static constexpr xdg_surface_listener surfaceListener = {
|
||||
.configure = SurfaceConfigEvent
|
||||
};
|
||||
|
||||
xdg_surface_add_listener(xdgSurface, &surfaceListener, this);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
xdgToplevel = xdg_surface_get_toplevel(xdgSurface);
|
||||
|
||||
static constexpr xdg_surface_listener surfaceListener = {SurfaceConfigure};
|
||||
static constexpr xdg_toplevel_listener topLevelListener = {
|
||||
.configure = ResizeEvent,
|
||||
.close = CloseEvent
|
||||
};
|
||||
|
||||
xdg_surface_add_listener(xdgSurface, &surfaceListener, nullptr);
|
||||
xdg_toplevel_add_listener(xdgToplevel, &topLevelListener, this);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
xdg_toplevel_set_title(xdgToplevel, title);
|
||||
wl_surface_commit(surface);
|
||||
xdg_toplevel_set_app_id(xdgToplevel, title);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
dec = zxdg_decoration_manager_v1_get_toplevel_decoration(decManager, xdgToplevel);
|
||||
zxdg_toplevel_decoration_v1_set_mode(dec, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
static constexpr wl_seat_listener seat_listener = {
|
||||
.capabilities = SeatCapabilitiesEvent
|
||||
};
|
||||
|
||||
wl_seat_add_listener(seat, &seat_listener, this);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
wl_surface_commit(wlSurface);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
this->scale = scale;
|
||||
created = true;
|
||||
|
||||
OnCreated();
|
||||
}
|
||||
|
||||
void Window::OnCreated()
|
||||
@@ -119,6 +289,15 @@ namespace ehs
|
||||
|
||||
void Window::Close()
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
zxdg_toplevel_decoration_v1_destroy(dec);
|
||||
dec = nullptr;
|
||||
|
||||
zxdg_decoration_manager_v1_destroy(decManager);
|
||||
decManager = nullptr;
|
||||
|
||||
xdg_toplevel_destroy(xdgToplevel);
|
||||
xdgToplevel = nullptr;
|
||||
|
||||
@@ -128,8 +307,8 @@ namespace ehs
|
||||
xdg_wm_base_destroy(xdgShell);
|
||||
xdgShell = nullptr;
|
||||
|
||||
wl_surface_destroy(surface);
|
||||
surface = nullptr;
|
||||
wl_surface_destroy(wlSurface);
|
||||
wlSurface = nullptr;
|
||||
|
||||
wl_compositor_destroy(compositor);
|
||||
compositor = nullptr;
|
||||
@@ -139,6 +318,8 @@ namespace ehs
|
||||
|
||||
wl_display_disconnect(display);
|
||||
display = nullptr;
|
||||
|
||||
created = false;
|
||||
}
|
||||
|
||||
void Window::Show()
|
||||
@@ -151,7 +332,11 @@ namespace ehs
|
||||
|
||||
bool Window::Poll()
|
||||
{
|
||||
wl_display_dispatch(display);
|
||||
if (wl_display_dispatch_pending(display) == -1)
|
||||
return false;
|
||||
|
||||
if (!created)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -206,7 +391,7 @@ namespace ehs
|
||||
|
||||
Vec2_u32 Window::GetScale() const
|
||||
{
|
||||
return {};
|
||||
return scale;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> Window::GetClipboard()
|
||||
|
@@ -112,7 +112,7 @@ namespace ehs
|
||||
server = xcb_connect(nullptr, nullptr);
|
||||
if (xcb_connection_has_error(server))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to connect to display server.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to connect to display server.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace ehs
|
||||
{
|
||||
xcb_disconnect(server);
|
||||
|
||||
EHS_LOG_INT("Warning", 1, "Failed to query for XCB XInput extension.");
|
||||
EHS_LOG_INT(LogType::WARN, 1, "Failed to query for XCB XInput extension.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace ehs
|
||||
{
|
||||
xcb_disconnect(server);
|
||||
|
||||
EHS_LOG_INT("Warning", 2, "XCB XInput extension is not available.");
|
||||
EHS_LOG_INT(LogType::WARN, 2, "XCB XInput extension is not available.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -187,8 +187,6 @@ namespace ehs
|
||||
|
||||
QueryPrimaryDevices();
|
||||
|
||||
xcb_map_window(server, hdl);
|
||||
|
||||
xcb_flush(server);
|
||||
|
||||
created = true;
|
||||
@@ -459,7 +457,7 @@ namespace ehs
|
||||
if (!reply || reply->status != XCB_GRAB_STATUS_SUCCESS)
|
||||
{
|
||||
free(reply);
|
||||
EHS_LOG_INT("Error", 0, "Failed to constrain cursor.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to constrain cursor.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -522,7 +520,7 @@ namespace ehs
|
||||
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(server, geom_cookie, nullptr);
|
||||
if (!geom)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve window position.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve window position.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -548,7 +546,7 @@ namespace ehs
|
||||
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(server, geom_cookie, nullptr);
|
||||
if (!geom)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve window scale.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve window scale.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -569,7 +567,7 @@ namespace ehs
|
||||
|
||||
if (clipboard_atom == XCB_ATOM_NONE || utf8_string_atom == XCB_ATOM_NONE || property_atom == XCB_ATOM_NONE)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve atoms.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve atoms.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -604,7 +602,7 @@ namespace ehs
|
||||
const xcb_atom_t clipboard_atom = RetrieveAtom(false, "CLIPBOARD");
|
||||
if (clipboard_atom == XCB_ATOM_NONE)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve atom.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve atom.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -683,7 +681,7 @@ namespace ehs
|
||||
|
||||
if (!device_reply)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to query primary devices.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to query primary devices.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -715,7 +713,7 @@ namespace ehs
|
||||
|
||||
if (!device_reply)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to query device name from the id, \"" + Str_8::FromNum(id) + "\".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to query device name from the id, \"" + Str_8::FromNum(id) + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -57,6 +57,54 @@ namespace ehs
|
||||
AddType("Audio");
|
||||
}
|
||||
|
||||
Audio::Audio(const Str_8& filePath)
|
||||
: Resource(File::ParseName_8(filePath)), sampleRate(0), dataType(DataType::FLOAT), byteDepth(0), channels(0),
|
||||
frames(0), length(0.0f), data(nullptr), peak(nullptr)
|
||||
{
|
||||
AddType("Audio");
|
||||
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
|
||||
const AudioCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
codec->Decode(data, this);
|
||||
}
|
||||
|
||||
Audio::Audio(const Str_8& filePath, DataType type)
|
||||
: Resource(File::ParseName_8(filePath)), sampleRate(0), dataType(DataType::FLOAT), byteDepth(0), channels(0),
|
||||
frames(0), length(0.0f), data(nullptr), peak(nullptr)
|
||||
{
|
||||
AddType("Audio");
|
||||
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
|
||||
const AudioCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
codec->Decode(data, this);
|
||||
|
||||
ToDataType(type);
|
||||
}
|
||||
|
||||
Audio::Audio(Str_8 id, const UInt_64 sampleRate, const DataType dataType, const UInt_8 channels, const UInt_64 frames, const Byte* const data)
|
||||
: Resource((Str_8&&)id), dataType(dataType), byteDepth(ToByteDepth(dataType)), sampleRate(sampleRate),
|
||||
channels(channels), frames(frames), length((float)frames / (float)sampleRate),
|
||||
@@ -105,13 +153,6 @@ namespace ehs
|
||||
AddType("Audio");
|
||||
}
|
||||
|
||||
Audio::Audio(Str_8 id)
|
||||
: Resource((Str_8&&)id), sampleRate(0), dataType(DataType::FLOAT), byteDepth(0), channels(0),
|
||||
frames(0), length(0.0f), data(nullptr), peak(nullptr)
|
||||
{
|
||||
AddType("Audio");
|
||||
}
|
||||
|
||||
Audio::Audio(Audio&& audio) noexcept
|
||||
: Resource((Resource&&)audio), sampleRate(audio.sampleRate), dataType(audio.dataType),
|
||||
byteDepth(audio.byteDepth), channels(audio.channels), frames(audio.frames), length(audio.length),
|
||||
@@ -291,7 +332,7 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to 2 channels is unsupported.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to 2 channels is unsupported.");
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -322,7 +363,7 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to 6 channels is unsupported.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to 6 channels is unsupported.");
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -353,7 +394,7 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to 8 channels is unsupported.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to 8 channels is unsupported.");
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -364,15 +405,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return ((SInt_8*)data)[sampleIndex];
|
||||
return ((SInt_8 *)data)[sampleIndex];
|
||||
case DataType::SINT_16:
|
||||
return (SInt_8)((float)((SInt_16*)data)[sampleIndex] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)((double)((SInt_16 *)data)[sampleIndex] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_8_MAX);
|
||||
case DataType::FLOAT:
|
||||
return (SInt_8)(((float*)data)[sampleIndex] * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)(((double *)data)[sampleIndex] * (double)EHS_SINT_8_MAX);
|
||||
case DataType::SINT_32:
|
||||
return (SInt_8)((float)((SInt_32*)data)[sampleIndex] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)((double)((SInt_32 *)data)[sampleIndex] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_8_MAX);
|
||||
case DataType::SINT_64:
|
||||
return (SInt_8)((float)((SInt_64*)data)[sampleIndex] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)((double)((SInt_64 *)data)[sampleIndex] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_8_MAX);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -383,15 +424,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return (SInt_16)((float)((SInt_8*)data)[sampleIndex] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)((double)((SInt_8*)data)[sampleIndex] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_16_MAX);
|
||||
case DataType::SINT_16:
|
||||
return ((SInt_16*)data)[sampleIndex];
|
||||
return ((SInt_16 *)data)[sampleIndex];
|
||||
case DataType::FLOAT:
|
||||
return (SInt_16)(((float*)data)[sampleIndex] * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)(((double *)data)[sampleIndex] * (double)EHS_SINT_16_MAX);
|
||||
case DataType::SINT_32:
|
||||
return (SInt_16)((float)((SInt_32*)data)[sampleIndex] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)((double)((SInt_32 *)data)[sampleIndex] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_16_MAX);
|
||||
case DataType::SINT_64:
|
||||
return (SInt_16)((float)((SInt_64*)data)[sampleIndex] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)((double)((SInt_64 *)data)[sampleIndex] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_16_MAX);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -421,15 +462,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return (SInt_32)((float)((SInt_8*)data)[sampleIndex] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)((double)((SInt_8 *)data)[sampleIndex] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_32_MAX);
|
||||
case DataType::SINT_16:
|
||||
return (SInt_32)((float)((SInt_16*)data)[sampleIndex] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)((double)((SInt_16 *)data)[sampleIndex] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_32_MAX);
|
||||
case DataType::FLOAT:
|
||||
return (SInt_32)(((float*)data)[sampleIndex] * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)(((double *)data)[sampleIndex] * (double)EHS_SINT_32_MAX);
|
||||
case DataType::SINT_32:
|
||||
return ((SInt_32*)data)[sampleIndex];
|
||||
return ((SInt_32 *)data)[sampleIndex];
|
||||
case DataType::SINT_64:
|
||||
return (SInt_32)((float)((SInt_64*)data)[sampleIndex] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)((double)((SInt_64 *)data)[sampleIndex] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_32_MAX);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -440,15 +481,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return (SInt_64)((float)((SInt_8*)data)[sampleIndex] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)((double)((SInt_8 *)data)[sampleIndex] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_64_MAX);
|
||||
case DataType::SINT_16:
|
||||
return (SInt_64)((float)((SInt_16*)data)[sampleIndex] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)((double)((SInt_16 *)data)[sampleIndex] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_64_MAX);
|
||||
case DataType::FLOAT:
|
||||
return (SInt_64)(((float*)data)[sampleIndex] * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)(((double *)data)[sampleIndex] * (double)EHS_SINT_64_MAX);
|
||||
case DataType::SINT_32:
|
||||
return (SInt_64)((float)((SInt_32*)data)[sampleIndex] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)((double)((SInt_32 *)data)[sampleIndex] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_64_MAX);
|
||||
case DataType::SINT_64:
|
||||
return ((SInt_64*)data)[sampleIndex];
|
||||
return ((SInt_64 *)data)[sampleIndex];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -461,13 +502,13 @@ namespace ehs
|
||||
case DataType::SINT_8:
|
||||
return *(SInt_8*)peak;
|
||||
case DataType::SINT_16:
|
||||
return (SInt_8)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)((double)*(SInt_16 *)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_8_MAX);
|
||||
case DataType::FLOAT:
|
||||
return (SInt_8)(*(float*)peak * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)(*(double *)peak * (double)EHS_SINT_8_MAX);
|
||||
case DataType::SINT_32:
|
||||
return (SInt_8)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)((double)*(SInt_32 *)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_8_MAX);
|
||||
case DataType::SINT_64:
|
||||
return (SInt_8)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_8_MAX);
|
||||
return (SInt_8)((double)*(SInt_64 *)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_8_MAX);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -478,15 +519,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return (SInt_16)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)((double)*(SInt_8 *)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_16_MAX);
|
||||
case DataType::SINT_16:
|
||||
return *(SInt_16*)peak;
|
||||
case DataType::FLOAT:
|
||||
return (SInt_16)(*(float*)peak * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)(*(double*)peak * (double)EHS_SINT_16_MAX);
|
||||
case DataType::SINT_32:
|
||||
return (SInt_16)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)((double)*(SInt_32 *)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_16_MAX);
|
||||
case DataType::SINT_64:
|
||||
return (SInt_16)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_16_MAX);
|
||||
return (SInt_16)((double)*(SInt_64 *)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_16_MAX);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -516,15 +557,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return (SInt_32)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)((double)*(SInt_8 *)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_32_MAX);
|
||||
case DataType::SINT_16:
|
||||
return (SInt_32)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)((double)*(SInt_16 *)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_32_MAX);
|
||||
case DataType::FLOAT:
|
||||
return (SInt_32)(*(float*)peak * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)(*(double *)peak * (double)EHS_SINT_32_MAX);
|
||||
case DataType::SINT_32:
|
||||
return *(SInt_32*)peak;
|
||||
return *(SInt_32 *)peak;
|
||||
case DataType::SINT_64:
|
||||
return (SInt_32)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_32_MAX);
|
||||
return (SInt_32)((double)*(SInt_64 *)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_32_MAX);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -535,15 +576,15 @@ namespace ehs
|
||||
switch (dataType)
|
||||
{
|
||||
case DataType::SINT_8:
|
||||
return (SInt_64)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)((double)*(SInt_8 *)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_64_MAX);
|
||||
case DataType::SINT_16:
|
||||
return (SInt_64)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)((double)*(SInt_16 *)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_64_MAX);
|
||||
case DataType::FLOAT:
|
||||
return (SInt_64)(*(float*)peak * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)(*(double *)peak * (double)EHS_SINT_64_MAX);
|
||||
case DataType::SINT_32:
|
||||
return (SInt_64)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX);
|
||||
return (SInt_64)((double)*(SInt_32 *)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_64_MAX);
|
||||
case DataType::SINT_64:
|
||||
return *(SInt_64*)peak;
|
||||
return *(SInt_64 *)peak;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -738,7 +779,7 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to " +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to " +
|
||||
Str_8::FromNum(newChannels) + " channels is unsupported.");
|
||||
return;
|
||||
}
|
||||
@@ -837,7 +878,7 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to " +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Conversion from " + Str_8::FromNum(channels) + " channels, to " +
|
||||
Str_8::FromNum(newChannels) + " channels is unsupported.");
|
||||
|
||||
return result;
|
||||
@@ -853,14 +894,14 @@ namespace ehs
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Audio::ToFile(const Str_8& filePath) const
|
||||
bool Audio::Export(const Str_8& filePath) const
|
||||
{
|
||||
Str_8 ext = File::ParseExt_8(filePath);
|
||||
|
||||
const AudioCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -874,96 +915,6 @@ namespace ehs
|
||||
return true;
|
||||
}
|
||||
|
||||
Audio Audio::FromFile(const Str_8& filePath)
|
||||
{
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
|
||||
Audio result(file.GetName());
|
||||
|
||||
const AudioCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
if (!codec->Decode(data, &result))
|
||||
return {};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Audio* Audio::FromFile_Heap(const Str_8& filePath)
|
||||
{
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
|
||||
Audio* result = nullptr;
|
||||
|
||||
const AudioCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = new Audio(file.GetName());
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
if (!codec->Decode(data, result))
|
||||
{
|
||||
delete result;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Audio Audio::FromFile(const Str_8& filePath, const DataType required)
|
||||
{
|
||||
Audio result = std::move(FromFile(filePath));
|
||||
if (!result.data)
|
||||
return result;
|
||||
|
||||
result.ToDataType(required);
|
||||
return result;
|
||||
}
|
||||
|
||||
Audio* Audio::FromFile_Heap(const Str_8& filePath, const DataType required)
|
||||
{
|
||||
Audio* result = FromFile_Heap(filePath);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
result->ToDataType(required);
|
||||
return result;
|
||||
}
|
||||
|
||||
Audio Audio::FromData(Str_8 id, const Str_8& ext, Serializer<UInt_64>& data)
|
||||
{
|
||||
Audio result((Str_8&&)id);
|
||||
|
||||
const AudioCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!codec->Decode(data, &result))
|
||||
return {};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Audio::ToMono(const UInt_64 newFrameCount, Byte* newData, const UInt_64 frameOffset) const
|
||||
{
|
||||
switch (dataType)
|
||||
@@ -1948,4 +1899,213 @@ namespace ehs
|
||||
|
||||
*(SInt_64*)newPeak = (SInt_64)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX);
|
||||
}
|
||||
|
||||
bool EncodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Audio* const in)
|
||||
{
|
||||
Serializer<UInt_64> result(codec->GetEndianness());
|
||||
result.WriteVersion({1, 0, 0});
|
||||
result.Write(in->GetSampleRate());
|
||||
result.Write(in->GetDataType());
|
||||
result.Write(in->GetByteDepth());
|
||||
result.Write(in->GetChannels());
|
||||
result.Write(in->GetFrameCount());
|
||||
|
||||
UInt_64 size = in->GetSize();
|
||||
UInt_8 byteDepth = in->GetByteDepth();
|
||||
|
||||
result.Resize(result.Size() + size + byteDepth);
|
||||
Util::Copy(&result[result.GetOffset()], &in[0], size);
|
||||
result.SetOffset(result.GetOffset() + size);
|
||||
|
||||
Util::Copy(&result[result.GetOffset()], in->GetPeak(), byteDepth);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Audio* const out)
|
||||
{
|
||||
Version version = in.ReadVersion();
|
||||
if (version != Version(1, 0, 0))
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Incompatible audio file version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_64 sampleRate = in.Read<UInt_64>();
|
||||
DataType dataType = in.Read<DataType>();
|
||||
UInt_8 byteDepth = in.Read<UInt_8>();
|
||||
UInt_8 channels = in.Read<UInt_8>();
|
||||
UInt_64 frames = in.Read<UInt_64>();
|
||||
|
||||
*out = Audio(out->GetId(), sampleRate, dataType, channels, frames);
|
||||
|
||||
UInt_64 size = out->GetSize();
|
||||
Util::Copy(&(*out)[0], &in[in.GetOffset()], size);
|
||||
in.SetOffset(in.GetOffset() + size);
|
||||
|
||||
out->SetPeak(byteDepth, &in[in.GetOffset()]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeWAV(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Audio* out)
|
||||
{
|
||||
RIFF riff(in);
|
||||
|
||||
if (riff.GetType() != "WAVE")
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Data is not in WAVE format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RIFF_Chunk fmt = riff.GetChunk("fmt ");
|
||||
if (!fmt.IsValid())
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Wave does not have a format chunk.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serializer<> fmtSer = fmt.GetData();
|
||||
|
||||
RIFF_Chunk dChunk = riff.GetChunk("data");
|
||||
if (!dChunk.IsValid())
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Wave does not have a data chunk.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_16 compression = fmtSer.Read<UInt_16>();
|
||||
if (compression == 0x2)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Microsoft ADPCM compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x6)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 4, "ITU G.711 a-law compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x7)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 5, "ITU G.711 µ-law compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x11)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 6, "IMA ADPCM compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x16)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 7, "TU G.723 ADPCM (Yamaha) compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x31)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 8, "GSM 6.10 compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x40)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 9, "ITU G.721 ADPCM compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0x50)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 10, "MPEG compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression == 0xFFFF)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 11, "Experimental compression unsupported.");
|
||||
return false;
|
||||
}
|
||||
else if (compression != 0x1 && compression != 0x3)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 12, "Wave has unknown compression of " + Str_8::FromNum(compression) + ".");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_16 channels = fmtSer.Read<UInt_16>();
|
||||
UInt_32 sampleRate = fmtSer.Read<UInt_32>();
|
||||
fmtSer.SetOffset(fmtSer.GetOffset() + 6);
|
||||
UInt_8 byteDepth = (UInt_8)(fmtSer.Read<UInt_16>() / 8);
|
||||
|
||||
DataType dataType;
|
||||
if (byteDepth == 1)
|
||||
dataType = DataType::SINT_8;
|
||||
else if (byteDepth == 2)
|
||||
dataType = DataType::SINT_16;
|
||||
else if (byteDepth == 3)
|
||||
dataType = DataType::SINT_24;
|
||||
else if (byteDepth == 4 && compression == 0x3)
|
||||
dataType = DataType::FLOAT;
|
||||
else if (byteDepth == 4)
|
||||
dataType = DataType::SINT_32;
|
||||
else if (byteDepth == 8)
|
||||
dataType = DataType::SINT_64;
|
||||
else
|
||||
return false;
|
||||
|
||||
UInt_64 size = dChunk.GetData().Size();
|
||||
UInt_64 frames = size / byteDepth / channels;
|
||||
|
||||
*out = Audio(out->GetId(), sampleRate, dataType, channels, frames);
|
||||
|
||||
Serializer<> dataSer = dChunk.GetData();
|
||||
|
||||
for (UInt_32 i = 0; i < dataSer.Size(); i += byteDepth)
|
||||
{
|
||||
if (byteDepth == 1)
|
||||
{
|
||||
*(SInt_8*)&(*out)[i] = dataSer.Read<SInt_8>();
|
||||
if ((*out)[i] > *(SInt_8*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_8), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 2)
|
||||
{
|
||||
*(SInt_16*)&(*out)[i] = dataSer.Read<SInt_16>();
|
||||
if (*(SInt_16*)&(*out)[i] > *(SInt_16*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_16), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 3)
|
||||
{
|
||||
*(SInt_16*)&(*out)[i + 1] = dataSer.Read<SInt_16>();
|
||||
(*out)[i] = dataSer.Read<Byte>();
|
||||
|
||||
SInt_32 signal = 0;
|
||||
signal |= (*out)[i];
|
||||
signal |= (*out)[i + 1] << 8;
|
||||
signal |= (*out)[i + 2] << 16;
|
||||
|
||||
SInt_32 peak = 0;
|
||||
peak |= out->GetPeak()[0];
|
||||
peak |= out->GetPeak()[1] << 8;
|
||||
peak |= out->GetPeak()[2] << 16;
|
||||
|
||||
if (signal > peak)
|
||||
out->SetPeak(3, &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 4 && compression == 0x3)
|
||||
{
|
||||
*(float*)&(*out)[i] = dataSer.Read<float>();
|
||||
if (*(float*)&(*out)[i] > *(float*)out->GetPeak())
|
||||
out->SetPeak(sizeof(float), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 4)
|
||||
{
|
||||
*(SInt_32*)&(*out)[i] = dataSer.Read<SInt_32>();
|
||||
if (*(SInt_32*)&(*out)[i] > *(SInt_32*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_32), &(*out)[i]);
|
||||
}
|
||||
else if (byteDepth == 8)
|
||||
{
|
||||
*(SInt_64*)&(*out)[i] = dataSer.Read<SInt_64>();
|
||||
if (*(SInt_64*)&(*out)[i] > *(SInt_64*)out->GetPeak())
|
||||
out->SetPeak(sizeof(SInt_64), &(*out)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -89,7 +89,7 @@ namespace ehs
|
||||
{
|
||||
if (!encodeCb)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Encoding is not supported for the " + id + " format.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Encoding is not supported for the " + id + " format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace ehs
|
||||
{
|
||||
if (!decodeCb)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Decoding is not supported for the " + id + " format.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Decoding is not supported for the " + id + " format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "ehs/io/audio/AudioDevice_ALSA.h"
|
||||
#include "ehs/EHS.h"
|
||||
#include "ehs/Log.h"
|
||||
#include "ehs/io/Console.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
@@ -77,7 +78,7 @@ namespace ehs
|
||||
|
||||
if (snd_pcm_hw_params_set_access(hdl, params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to set access.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to set access.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ namespace ehs
|
||||
}
|
||||
default:
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Invalid data type.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Invalid data type.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -125,7 +126,7 @@ namespace ehs
|
||||
{
|
||||
if (snd_pcm_hw_params_set_channels_near(hdl, params, &channels) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to set channels.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to set channels.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -134,26 +135,26 @@ namespace ehs
|
||||
{
|
||||
if (snd_pcm_hw_params_set_rate_near(hdl, params, &sampleRate, nullptr) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to set sample rate.");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to set sample rate.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (snd_pcm_hw_params_set_period_time_near(hdl, params, &period, nullptr) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to set period.");
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to set period.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd_pcm_hw_params_set_buffer_time_near(hdl, params, &latency, nullptr) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 4, "Failed to set latency.");
|
||||
EHS_LOG_INT(LogType::ERR, 4, "Failed to set latency.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd_pcm_hw_params(hdl, params) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 5, "Failed to apply hardware parameters.");
|
||||
EHS_LOG_INT(LogType::ERR, 5, "Failed to apply hardware parameters.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,7 +163,7 @@ namespace ehs
|
||||
snd_pcm_format_t format;
|
||||
if (snd_pcm_hw_params_get_format(params, &format) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 6, "Failed to retrieve audio device properties.");
|
||||
EHS_LOG_INT(LogType::ERR, 6, "Failed to retrieve audio device properties.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -200,7 +201,7 @@ namespace ehs
|
||||
}
|
||||
default:
|
||||
{
|
||||
EHS_LOG_INT("Error", 7, "Format unsupported.");
|
||||
EHS_LOG_INT(LogType::ERR, 7, "Format unsupported.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +211,7 @@ namespace ehs
|
||||
{
|
||||
if (snd_pcm_hw_params_get_channels(params, &channels) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 8, "Failed to retrieve channel count.");
|
||||
EHS_LOG_INT(LogType::ERR, 8, "Failed to retrieve channel count.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -220,14 +221,14 @@ namespace ehs
|
||||
int dir;
|
||||
if (snd_pcm_hw_params_get_rate(params, &sampleRate, &dir) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 9, "Failed to retrieve sample rate.");
|
||||
EHS_LOG_INT(LogType::ERR, 9, "Failed to retrieve sample rate.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (snd_pcm_hw_params_get_buffer_size(params, &maxFrames) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 10, "Failed to retrieve buffer size.");
|
||||
EHS_LOG_INT(LogType::ERR, 10, "Failed to retrieve buffer size.");
|
||||
}
|
||||
|
||||
snd_pcm_sw_params_t* swParams = nullptr;
|
||||
@@ -235,31 +236,31 @@ namespace ehs
|
||||
|
||||
if (snd_pcm_sw_params_current(hdl, swParams) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 11, "Failed to retrieve software parameters.");
|
||||
EHS_LOG_INT(LogType::ERR, 11, "Failed to retrieve software parameters.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd_pcm_sw_params_set_silence_threshold(hdl, swParams, maxFrames) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 12, "Failed to set silence threshold.");
|
||||
EHS_LOG_INT(LogType::ERR, 12, "Failed to set silence threshold.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd_pcm_sw_params_set_silence_size(hdl, swParams, maxFrames) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 12, "Failed to set silence size.");
|
||||
EHS_LOG_INT(LogType::ERR, 12, "Failed to set silence size.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd_pcm_sw_params(hdl, swParams) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 13, "Failed to set software parameters.");
|
||||
EHS_LOG_INT(LogType::ERR, 13, "Failed to set software parameters.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd_pcm_prepare(hdl) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 14, "Failed to prepare audio stream.");
|
||||
EHS_LOG_INT(LogType::ERR, 14, "Failed to prepare audio stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -281,10 +282,10 @@ namespace ehs
|
||||
snd_pcm_state_t state = snd_pcm_state(hdl);
|
||||
if (state == SND_PCM_STATE_XRUN)
|
||||
{
|
||||
EHS_LOG_INT("Warning", 0, "Buffer overrun/underrun occurred.");
|
||||
EHS_LOG_INT(LogType::WARN, 0, "Buffer overrun/underrun occurred.");
|
||||
if (snd_pcm_recover(hdl, -EPIPE, 0) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to recover from buffer overrun/underrun.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to recover from buffer overrun/underrun.");
|
||||
return 0;
|
||||
}
|
||||
return GetAvailFrames();
|
||||
@@ -293,7 +294,7 @@ namespace ehs
|
||||
{
|
||||
if (snd_pcm_start(hdl) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to start audio stream.");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to start audio stream.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -305,10 +306,10 @@ namespace ehs
|
||||
{
|
||||
if (frames == -EPIPE)
|
||||
{
|
||||
EHS_LOG_INT("Warning", 3, "Buffer overrun/underrun occurred.");
|
||||
EHS_LOG_INT(LogType::WARN, 3, "Buffer overrun/underrun occurred.");
|
||||
if (snd_pcm_recover(hdl, -EPIPE, 1) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 4, "Failed to recover from buffer overrun/underrun.");
|
||||
EHS_LOG_INT(LogType::ERR, 4, "Failed to recover from buffer overrun/underrun.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -316,7 +317,7 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 5, "Failed to retrieve available frames with error #" + Str_8::FromNum(frames) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 5, "Failed to retrieve available frames with error #" + Str_8::FromNum(frames) + ".");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -329,7 +330,7 @@ namespace ehs
|
||||
const snd_pcm_channel_area_t* areas;
|
||||
if (snd_pcm_mmap_begin(hdl, &areas, offset, frames) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to map audio buffer.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to map audio buffer.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -341,7 +342,7 @@ namespace ehs
|
||||
snd_pcm_sframes_t committed = snd_pcm_mmap_commit(hdl, offset, frames);
|
||||
if (committed < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to commit mapped audio buffer.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to commit mapped audio buffer.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -366,13 +367,21 @@ namespace ehs
|
||||
}
|
||||
else
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Wrong value for the audio device type.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Wrong value for the audio device type.");
|
||||
return {};
|
||||
}
|
||||
|
||||
int err = snd_pcm_open(&result.hdl, "default", rType, SND_PCM_NONBLOCK);
|
||||
if (err < 0)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve default audio device with error #" + Str_8::FromNum(err) + ".");
|
||||
return {};
|
||||
}
|
||||
|
||||
snd_pcm_open(&result.hdl, "default", rType, SND_PCM_NONBLOCK);
|
||||
result.type = AudioDeviceType::OUTPUT;
|
||||
|
||||
EHS_LOG_SUCCESS();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -380,4 +389,4 @@ namespace ehs
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ namespace ehs
|
||||
HRESULT r = client->Stop();
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to stop audio with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to stop audio with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace ehs
|
||||
|
||||
HRESULT r = hdl->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&client);
|
||||
if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 0, "Failed to create audio client with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to create audio client with error #" + Str_8::FromNum(r) + ".");
|
||||
|
||||
WAVEFORMATEXTENSIBLE* format;
|
||||
client->GetMixFormat((WAVEFORMATEX**)&format);
|
||||
@@ -146,7 +146,7 @@ namespace ehs
|
||||
{
|
||||
if (r == AUDCLNT_E_UNSUPPORTED_FORMAT)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1,
|
||||
EHS_LOG_INT(LogType::ERR, 1,
|
||||
"The audio device, \"" + GetName_8() + "\" doesn't support the format {" +
|
||||
Str_8::FromNum(format->Format.wBitsPerSample) + "-bit, " +
|
||||
Str_8::FromNum(format->Format.nSamplesPerSec) + "Hz, " +
|
||||
@@ -154,14 +154,14 @@ namespace ehs
|
||||
);
|
||||
}
|
||||
else
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve supported audio format with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve supported audio format with error #" + Str_8::FromNum(r) + ".");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (match)
|
||||
{
|
||||
EHS_LOG_INT("Error", 3,
|
||||
EHS_LOG_INT(LogType::ERR, 3,
|
||||
"The audio device, \"" + GetName_8() + "\" doesn't support the format {" +
|
||||
Str_8::FromNum(format->Format.wBitsPerSample) + "-bit, " +
|
||||
Str_8::FromNum(format->Format.nSamplesPerSec) + "Hz, " +
|
||||
@@ -185,78 +185,78 @@ namespace ehs
|
||||
|
||||
if (r == AUDCLNT_E_ALREADY_INITIALIZED)
|
||||
{
|
||||
EHS_LOG_INT("Error", 5, "Audio client is already initialized.");
|
||||
EHS_LOG_INT(LogType::ERR, 5, "Audio client is already initialized.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_WRONG_ENDPOINT_TYPE)
|
||||
{
|
||||
EHS_LOG_INT("Error", 6, "The AUDCLNT_STREAMFLAGS_LOOPBACK flag is set but the endpoint device is a capture device, not a rendering device.");
|
||||
EHS_LOG_INT(LogType::ERR, 6, "The AUDCLNT_STREAMFLAGS_LOOPBACK flag is set but the endpoint device is a capture device, not a rendering device.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_BUFFER_SIZE_ERROR)
|
||||
{
|
||||
EHS_LOG_INT("Error", 7, "Indicates that the buffer duration value requested by an exclusive-mode client is out of range. The requested duration value for pull mode must not be greater than 5000 milliseconds; for push mode the duration value must not be greater than 2 seconds.");
|
||||
EHS_LOG_INT(LogType::ERR, 7, "Indicates that the buffer duration value requested by an exclusive-mode client is out of range. The requested duration value for pull mode must not be greater than 5000 milliseconds; for push mode the duration value must not be greater than 2 seconds.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_CPUUSAGE_EXCEEDED)
|
||||
{
|
||||
EHS_LOG_INT("Error", 8, "The audio endpoint device has been unplugged, or the audio hardware or associated hardware resources have been reconfigured, disabled, removed, or otherwise made unavailable for use.");
|
||||
EHS_LOG_INT(LogType::ERR, 8, "The audio endpoint device has been unplugged, or the audio hardware or associated hardware resources have been reconfigured, disabled, removed, or otherwise made unavailable for use.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_DEVICE_IN_USE)
|
||||
{
|
||||
EHS_LOG_INT("Error", 9, "The endpoint device is already in use. Either the device is being used in exclusive mode, or the device is being used in shared mode and the caller asked to use the device in exclusive mode.");
|
||||
EHS_LOG_INT(LogType::ERR, 9, "The endpoint device is already in use. Either the device is being used in exclusive mode, or the device is being used in shared mode and the caller asked to use the device in exclusive mode.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_ENDPOINT_CREATE_FAILED)
|
||||
{
|
||||
EHS_LOG_INT("Error", 10, "The method failed to create the audio endpoint for the render or the capture device. This can occur if the audio endpoint device has been unplugged, or the audio hardware or associated hardware resources have been reconfigured, disabled, removed, or otherwise made unavailable for use.");
|
||||
EHS_LOG_INT(LogType::ERR, 10, "The method failed to create the audio endpoint for the render or the capture device. This can occur if the audio endpoint device has been unplugged, or the audio hardware or associated hardware resources have been reconfigured, disabled, removed, or otherwise made unavailable for use.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_INVALID_DEVICE_PERIOD)
|
||||
{
|
||||
EHS_LOG_INT("Error", 11, "Indicates that the device period requested by an exclusive-mode client is greater than 5000 milliseconds.");
|
||||
EHS_LOG_INT(LogType::ERR, 11, "Indicates that the device period requested by an exclusive-mode client is greater than 5000 milliseconds.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_UNSUPPORTED_FORMAT)
|
||||
{
|
||||
EHS_LOG_INT("Error", 12, "The audio engine (shared mode) or audio endpoint device (exclusive mode) does not support the specified format.");
|
||||
EHS_LOG_INT(LogType::ERR, 12, "The audio engine (shared mode) or audio endpoint device (exclusive mode) does not support the specified format.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED)
|
||||
{
|
||||
EHS_LOG_INT("Error", 13, "The caller is requesting exclusive-mode use of the endpoint device, but the user has disabled exclusive-mode use of the device.");
|
||||
EHS_LOG_INT(LogType::ERR, 13, "The caller is requesting exclusive-mode use of the endpoint device, but the user has disabled exclusive-mode use of the device.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL)
|
||||
{
|
||||
EHS_LOG_INT("Error", 14, "The AUDCLNT_STREAMFLAGS_EVENTCALLBACK flag is set but parameters hnsBufferDuration and hnsPeriodicity are not equal.");
|
||||
EHS_LOG_INT(LogType::ERR, 14, "The AUDCLNT_STREAMFLAGS_EVENTCALLBACK flag is set but parameters hnsBufferDuration and hnsPeriodicity are not equal.");
|
||||
return;
|
||||
}
|
||||
else if (r == AUDCLNT_E_SERVICE_NOT_RUNNING)
|
||||
{
|
||||
EHS_LOG_INT("Error", 15, "The Windows audio service is not running.");
|
||||
EHS_LOG_INT(LogType::ERR, 15, "The Windows audio service is not running.");
|
||||
return;
|
||||
}
|
||||
else if (r == E_POINTER)
|
||||
{
|
||||
EHS_LOG_INT("Error", 16, "Parameter pFormat is NULL.");
|
||||
EHS_LOG_INT(LogType::ERR, 16, "Parameter pFormat is NULL.");
|
||||
return;
|
||||
}
|
||||
else if (r == E_INVALIDARG)
|
||||
{
|
||||
EHS_LOG_INT("Error", 17, "Parameter pFormat points to an invalid format description; or the AUDCLNT_STREAMFLAGS_LOOPBACK flag is set but ShareMode is not equal to AUDCLNT_SHAREMODE_SHARED; or the AUDCLNT_STREAMFLAGS_CROSSPROCESS flag is set but ShareMode is equal to AUDCLNT_SHAREMODE_EXCLUSIVE.\n"
|
||||
EHS_LOG_INT(LogType::ERR, 17, "Parameter pFormat points to an invalid format description; or the AUDCLNT_STREAMFLAGS_LOOPBACK flag is set but ShareMode is not equal to AUDCLNT_SHAREMODE_SHARED; or the AUDCLNT_STREAMFLAGS_CROSSPROCESS flag is set but ShareMode is equal to AUDCLNT_SHAREMODE_EXCLUSIVE.\n"
|
||||
"A prior call to SetClientProperties was made with an invalid category for audio/render streams.");
|
||||
return;
|
||||
}
|
||||
else if (r == E_OUTOFMEMORY)
|
||||
{
|
||||
EHS_LOG_INT("Error", 18, "Out of memory.");
|
||||
EHS_LOG_INT(LogType::ERR, 18, "Out of memory.");
|
||||
return;
|
||||
}
|
||||
else if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 19, "Failed to initialize audio stream with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 19, "Failed to initialize audio stream with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace ehs
|
||||
r = client->GetService(__uuidof(IAudioRenderClient), (void**)&playbackClient);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 27, "Failed to retrieve audio render client with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 27, "Failed to retrieve audio render client with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -274,7 +274,7 @@ namespace ehs
|
||||
r = client->GetService(__uuidof(IAudioCaptureClient), (void**)&captureClient);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 28, "Failed to retrieve audio capture client with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 28, "Failed to retrieve audio capture client with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -282,14 +282,14 @@ namespace ehs
|
||||
r = client->GetBufferSize((UINT32*)&maxFrames);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 29, "Failed to retrieve buffer size with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 29, "Failed to retrieve buffer size with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
r = client->Start();
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 30, "Failed to start audio with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 30, "Failed to start audio with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace ehs
|
||||
HRESULT r = client->Stop();
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to stop audio with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to stop audio with error #" + Str_8::FromNum(r) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -340,9 +340,9 @@ namespace ehs
|
||||
{
|
||||
HRESULT r = client->GetCurrentPadding(&sampleSize);
|
||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 0, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
|
||||
|
||||
sampleSize = maxFrames - sampleSize;
|
||||
}
|
||||
@@ -350,9 +350,9 @@ namespace ehs
|
||||
{
|
||||
HRESULT r = captureClient->GetNextPacketSize(&sampleSize);
|
||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 0, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve samples size with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples size with error #" + Str_8::FromNum(r) + ".");
|
||||
}
|
||||
|
||||
return sampleSize;
|
||||
@@ -367,19 +367,19 @@ namespace ehs
|
||||
|
||||
HRESULT r = client->GetCurrentPadding((UINT32*)&offset);
|
||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 0, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
|
||||
|
||||
if (playbackClient)
|
||||
{
|
||||
r = playbackClient->GetBuffer(*frames, &buffer);
|
||||
if (r == AUDCLNT_E_BUFFER_TOO_LARGE)
|
||||
EHS_LOG_INT("Error", 0, "The given frame size, " + Str_8::FromNum(*frames) + ", must be less than or equal to, " + Str_8::FromNum(maxFrames - *offset) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The given frame size, " + Str_8::FromNum(*frames) + ", must be less than or equal to, " + Str_8::FromNum(maxFrames - *offset) + ".");
|
||||
else if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 1, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
}
|
||||
else if (captureClient)
|
||||
{
|
||||
@@ -387,9 +387,9 @@ namespace ehs
|
||||
|
||||
r = captureClient->GetBuffer(&buffer, (UINT32*)frames, (DWORD*)&flags, nullptr, nullptr);
|
||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 1, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@@ -404,17 +404,17 @@ namespace ehs
|
||||
{
|
||||
HRESULT r = playbackClient->ReleaseBuffer(frames, 0);
|
||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 0, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
}
|
||||
else if (captureClient)
|
||||
{
|
||||
HRESULT r = captureClient->ReleaseBuffer(frames);
|
||||
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||
EHS_LOG_INT("Error", 0, "The audio device has been invalidated.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
|
||||
else if (FAILED(r))
|
||||
EHS_LOG_INT("Error", 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +429,7 @@ namespace ehs
|
||||
HRESULT r = hdl->OpenPropertyStore(STGM_READ, &pProps);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve interface name with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve interface name with error #" + Str_8::FromNum(r) + ".");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace ehs
|
||||
HRESULT r = hdl->OpenPropertyStore(STGM_READ, &pProps);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve name with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve name with error #" + Str_8::FromNum(r) + ".");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ namespace ehs
|
||||
HRESULT r = CoInitialize(nullptr);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to initialize COM with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to initialize COM with error #" + Str_8::FromNum(r) + ".");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ namespace ehs
|
||||
r = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&enumerator);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to initialize WASAPI with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to initialize WASAPI with error #" + Str_8::FromNum(r) + ".");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace ehs
|
||||
r = enumerator->GetDefaultAudioEndpoint((EDataFlow)type, eConsole, &deviceHdl);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve default audio output device with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve default audio output device with error #" + Str_8::FromNum(r) + ".");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ namespace ehs
|
||||
HRESULT r = CoInitialize(nullptr);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to initialize COM with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Failed to initialize COM with error #" + Str_8::FromNum(r) + ".");
|
||||
return devices;
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ namespace ehs
|
||||
r = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&enumerator);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to initialize WASAPI with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Failed to initialize WASAPI with error #" + Str_8::FromNum(r) + ".");
|
||||
return devices;
|
||||
}
|
||||
|
||||
@@ -547,7 +547,7 @@ namespace ehs
|
||||
r = enumerator->EnumAudioEndpoints((EDataFlow)type, (DWORD)state, &collection);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve audio device collection with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve audio device collection with error #" + Str_8::FromNum(r) + ".");
|
||||
return devices;
|
||||
}
|
||||
|
||||
@@ -555,7 +555,7 @@ namespace ehs
|
||||
r = collection->GetCount((UINT*)&count);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to retrieve audio device count with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Failed to retrieve audio device count with error #" + Str_8::FromNum(r) + ".");
|
||||
return devices;
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ namespace ehs
|
||||
r = collection->Item(i, &deviceHdl);
|
||||
if (FAILED(r))
|
||||
{
|
||||
EHS_LOG_INT("Error", 4, "Failed to retrieve audio device with error #" + Str_8::FromNum(r) + ".");
|
||||
EHS_LOG_INT(LogType::ERR, 4, "Failed to retrieve audio device with error #" + Str_8::FromNum(r) + ".");
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,7 @@
|
||||
#include "ehs/io/img/Img.h"
|
||||
#include "ehs/io/img/PNG.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
@@ -53,6 +56,30 @@ namespace ehs
|
||||
AddType("Img");
|
||||
}
|
||||
|
||||
Img::Img(const Str_8& filePath)
|
||||
: byteDepth(0), channels(0), size(0), data(nullptr)
|
||||
{
|
||||
AddType("Img");
|
||||
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
hashId = file.GetName().Hash_64();
|
||||
id = file.GetName();
|
||||
|
||||
const ImgCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> inData = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
codec->Decode(inData, this);
|
||||
}
|
||||
|
||||
Img::Img(Str_8 id, const UInt_8 byteDepth, const UInt_8 channels, const Vec2_u64& resolution, const Byte* const data)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), byteDepth(byteDepth), channels(channels), resolution(resolution),
|
||||
size(resolution.x * byteDepth * channels * resolution.y), data(new Byte[size])
|
||||
@@ -69,12 +96,6 @@ namespace ehs
|
||||
AddType("Img");
|
||||
}
|
||||
|
||||
Img::Img(Str_8 id)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), byteDepth(0), channels(0), size(0), data(nullptr)
|
||||
{
|
||||
AddType("Img");
|
||||
}
|
||||
|
||||
Img::Img(Img&& img) noexcept
|
||||
: BaseObj((BaseObj&&)img), hashId(img.hashId), id((Str_8&&)img.id), byteDepth(img.byteDepth),
|
||||
channels(img.channels), resolution(img.resolution), size(img.size), data(img.data)
|
||||
@@ -849,14 +870,14 @@ namespace ehs
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Img::ToFile(const Str_8& filePath) const
|
||||
bool Img::Export(const Str_8& filePath) const
|
||||
{
|
||||
Str_8 ext = File::ParseExt_8(filePath);
|
||||
|
||||
const ImgCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -870,76 +891,6 @@ namespace ehs
|
||||
return true;
|
||||
}
|
||||
|
||||
Img Img::FromFile(const Str_8& filePath)
|
||||
{
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
|
||||
Img result(file.GetName());
|
||||
|
||||
const ImgCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
if (!codec->Decode(data, &result))
|
||||
return {};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Img* Img::FromFile_Heap(const Str_8& filePath)
|
||||
{
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
Str_8 ext = file.GetExtension();
|
||||
|
||||
Img* result = nullptr;
|
||||
|
||||
const ImgCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = new Img(file.GetName());
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
if (!codec->Decode(data, result))
|
||||
{
|
||||
delete result;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Img Img::FromData(Str_8 id, const Str_8& ext, Serializer<UInt_64>& data)
|
||||
{
|
||||
Img result((Str_8&&)id);
|
||||
|
||||
const ImgCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!codec->Decode(data, &result))
|
||||
return {};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Img Img::GetNearestNeighbor(const Vec2_u64& newResolution) const
|
||||
{
|
||||
Img result(id, byteDepth, channels, newResolution);
|
||||
@@ -1485,4 +1436,320 @@ namespace ehs
|
||||
for (UInt_64 i = 0, n = 0; i < newSize; ++i, n += 2)
|
||||
buffer[i] = (Byte)((float)*(UInt_16*)&data[n] / (float)EHS_UINT_16_MAX * (float)EHS_UINT_8_MAX);
|
||||
}
|
||||
|
||||
bool EncodeQOI(const ehs::ImgCodec* const codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Img* in)
|
||||
{
|
||||
UInt_8 channels = in->GetChannels();
|
||||
Vec2_u64 resolution = in->GetResolution();
|
||||
|
||||
UInt_32 px_len = resolution.x * resolution.y * channels;
|
||||
UInt_32 px_end = px_len - channels;
|
||||
|
||||
Byte index[256];
|
||||
for (UInt_64 i = 0; i < 64; ++i)
|
||||
*(UInt_32*)&index[i * 4] = 0;
|
||||
|
||||
Byte prevPixel[4] = {0, 0, 0, 255};
|
||||
Byte pixel[4] = {0, 0, 0, 255};
|
||||
|
||||
Serializer<UInt_32> result(Endianness::BE, resolution.x * resolution.y * (channels + 1) + 22);
|
||||
|
||||
result.Write('q');
|
||||
result.Write('o');
|
||||
result.Write('i');
|
||||
result.Write('f');
|
||||
result.Write<UInt_32>(resolution.x);
|
||||
result.Write<UInt_32>(resolution.y);
|
||||
result.Write(in->GetChannels());
|
||||
result.Write(1);
|
||||
|
||||
for (UInt_32 px_pos = 0, run = 0; px_pos < px_len; px_pos += channels)
|
||||
{
|
||||
if (channels == 4)
|
||||
{
|
||||
*(UInt_32*)pixel = *(UInt_32*)&(*in)[px_pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel[0] = (*in)[px_pos];
|
||||
pixel[1] = (*in)[px_pos + 1];
|
||||
pixel[2] = (*in)[px_pos + 2];
|
||||
}
|
||||
|
||||
if (*(UInt_32*)pixel == *(UInt_32*)prevPixel)
|
||||
{
|
||||
run++;
|
||||
if (run == 62 || px_pos == px_end)
|
||||
{
|
||||
result.Write<UInt_8>(0xc0 | (run - 1));
|
||||
run = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (run > 0)
|
||||
{
|
||||
result.Write<UInt_8>(0xc0 | (run - 1));
|
||||
run = 0;
|
||||
}
|
||||
|
||||
UInt_32 index_pos = (prevPixel[0] * 3 + prevPixel[1] * 5 + prevPixel[2] * 7 + prevPixel[3] * 11) % 64 * channels;
|
||||
|
||||
if (*(UInt_32*)&index[index_pos] == *(UInt_32*)pixel)
|
||||
{
|
||||
result.Write<UInt_8>(0x00 | (index_pos / channels));
|
||||
}
|
||||
else
|
||||
{
|
||||
*(UInt_32*)&index[index_pos] = *(UInt_32*)pixel;
|
||||
|
||||
if (pixel[3] == prevPixel[3])
|
||||
{
|
||||
SInt_8 vr = pixel[0] - prevPixel[0];
|
||||
SInt_8 vg = pixel[1] - prevPixel[1];
|
||||
SInt_8 vb = pixel[2] - prevPixel[2];
|
||||
|
||||
SInt_8 vg_r = vr - vg;
|
||||
SInt_8 vg_b = vb - vg;
|
||||
|
||||
if (
|
||||
vr > -3 && vr < 2 &&
|
||||
vg > -3 && vg < 2 &&
|
||||
vb > -3 && vb < 2
|
||||
)
|
||||
{
|
||||
result.Write<UInt_8>(0x40 | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2));
|
||||
}
|
||||
else if (
|
||||
vg_r > -9 && vg_r < 8 &&
|
||||
vg > -33 && vg < 32 &&
|
||||
vg_b > -9 && vg_b < 8
|
||||
)
|
||||
{
|
||||
result.Write<UInt_8>(0x80 | (vg + 32));
|
||||
result.Write<UInt_8>((vg_r + 8) << 4 | (vg_b + 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Write<UInt_8>(0xfe);
|
||||
result.Write(pixel[0]);
|
||||
result.Write(pixel[1]);
|
||||
result.Write(pixel[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Write<UInt_8>(0xff);
|
||||
result.SetEndianness(CPU::GetEndianness());
|
||||
result.Write(*(UInt_32*)pixel);
|
||||
result.SetEndianness(Endianness::BE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*(UInt_32*)prevPixel = *(UInt_32*)pixel;
|
||||
}
|
||||
|
||||
result.Write(0x100000000000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeQOI(const ehs::ImgCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Img* out)
|
||||
{
|
||||
Str_8 imgType = in.ReadStr<Char_8, UInt_64>(4);
|
||||
if (imgType != "qoif")
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Given data is not in the qoif format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_64 width = in.Read<UInt_32>();
|
||||
UInt_64 height = in.Read<UInt_32>();
|
||||
|
||||
UInt_8 channels = in.Read<UInt_8>();
|
||||
channels = 4;
|
||||
UInt_8 space = in.Read<UInt_8>();
|
||||
UInt_8 bitDepth = 8;
|
||||
|
||||
UInt_64 size = width * channels * height;
|
||||
|
||||
*out = Img(out->GetId(), bitDepth / 8, channels, {width, height});
|
||||
|
||||
Byte prevPixel[4] = {0, 0, 0, 255};
|
||||
|
||||
Byte index[256];
|
||||
for (UInt_64 i = 0; i < 64; ++i)
|
||||
*(UInt_32*)&index[i * 4] = 0;
|
||||
|
||||
UInt_32 chunksLen = in.Size() - 8;
|
||||
for (UInt_32 pos = 0, run = 0; pos < size; pos += channels)
|
||||
{
|
||||
if (run > 0)
|
||||
--run;
|
||||
else if (in.GetOffset() < chunksLen)
|
||||
{
|
||||
UInt_32 chunkType = (UInt_32)in.Read<UInt_8>();
|
||||
if (chunkType == 0xfe) // RGB
|
||||
{
|
||||
prevPixel[0] = in.Read<UInt_8>(); // R-value
|
||||
prevPixel[1] = in.Read<UInt_8>(); // G-value
|
||||
prevPixel[2] = in.Read<UInt_8>(); // B-value
|
||||
}
|
||||
else if (chunkType == 0xff) // RGBA
|
||||
{
|
||||
*(UInt_32*)prevPixel = in.Read<UInt_32>();
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0x00) // Index
|
||||
{
|
||||
*(UInt_32*)prevPixel = *(UInt_32*)&index[chunkType * channels];
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0x40) // Diff
|
||||
{
|
||||
prevPixel[0] += ((chunkType >> 4) & 0x03) - 2; // R-value
|
||||
prevPixel[1] += ((chunkType >> 2) & 0x03) - 2; // G-value
|
||||
prevPixel[2] += (chunkType & 0x03) - 2; // B-value
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0x80) // Luma
|
||||
{
|
||||
UInt_32 mod = (UInt_32)in.Read<UInt_8>();
|
||||
UInt_32 vg = (chunkType & 0x3f) - 32;
|
||||
prevPixel[0] += vg - 8 + ((mod >> 4) & 0x0f); // R-value
|
||||
prevPixel[1] += vg; // G-value
|
||||
prevPixel[2] += vg - 8 + (mod & 0x0f); // B-value
|
||||
}
|
||||
else if ((chunkType & 0xc0) == 0xc0) // Run
|
||||
run = (chunkType & 0x3f);
|
||||
|
||||
*(UInt_32*)&index[(prevPixel[0] * 3 + prevPixel[1] * 5 + prevPixel[2] * 7 + prevPixel[3] * 11) % 64 * channels] = *(UInt_32*)prevPixel;
|
||||
}
|
||||
|
||||
if (channels == 4)
|
||||
{
|
||||
*((UInt_32*)&(*out)[pos]) = *(UInt_32*)prevPixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*out)[pos] = prevPixel[0];
|
||||
(*out)[pos + 1] = prevPixel[1];
|
||||
(*out)[pos + 2] = prevPixel[2];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodePNG(const ehs::ImgCodec* const codec, ehs::Serializer<ehs::UInt_64>& in, ehs::Img* out)
|
||||
{
|
||||
PNG png(out->GetId(), in);
|
||||
|
||||
PNG_Chunk* ihdr = png.GetChunk("IHDR");
|
||||
Serializer<UInt_64>* ihdrData = ihdr->GetData();
|
||||
|
||||
UInt_32 width = ihdrData->Read<UInt_32>();
|
||||
UInt_32 height = ihdrData->Read<UInt_32>();
|
||||
UInt_8 bitDepth = ihdrData->Read<UInt_8>();
|
||||
|
||||
UInt_8 colorType = ihdrData->Read<UInt_8>();
|
||||
if (colorType == 3)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 1, "Color type of " + Str_8::FromNum(colorType) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_8 channels = 1;
|
||||
if (colorType == 2)
|
||||
channels = 3;
|
||||
else if (colorType == 4)
|
||||
channels = 2;
|
||||
else if (colorType == 6)
|
||||
channels = 4;
|
||||
|
||||
*out = Img(out->GetId(), bitDepth / 8, channels, {width, height});
|
||||
|
||||
UInt_8 compression = ihdrData->Read<UInt_8>();
|
||||
if (compression)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 2, "Compression method of " + Str_8::FromNum(compression) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_8 filter = ihdrData->Read<UInt_8>();
|
||||
if (filter)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 3, "Filter method of " + Str_8::FromNum(filter) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_8 interlaced = ihdrData->Read<UInt_8>();
|
||||
if (interlaced)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 4, "Interlacing method of " + Str_8::FromNum(interlaced) + " is unsupported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt_32 scanline = width * (bitDepth / 8) * channels;
|
||||
UInt_32 scanLineF = scanline + 1;
|
||||
UInt_32 bufferSize = scanline * height + height;
|
||||
|
||||
Byte* buffer = new Byte[bufferSize];
|
||||
|
||||
PNG_Chunk* idat = png.GetChunk("IDAT");
|
||||
Serializer<UInt_64>* idatData = idat->GetData();
|
||||
|
||||
z_stream strm = {};
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = idatData->Size();
|
||||
strm.next_in = *idatData;
|
||||
strm.avail_out = bufferSize;
|
||||
strm.next_out = buffer;
|
||||
|
||||
int code = inflateInit(&strm);
|
||||
if (code != Z_OK)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 5, "Failed to initialize zlib inflate with error #" + Str_8::FromNum(code) + ".");
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
code = inflate(&strm, Z_NO_FLUSH);
|
||||
if (code != Z_STREAM_END && code != Z_OK)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 6, "Failed to zlib inflate with error #" + Str_8::FromNum(code) + ".");
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
} while (strm.avail_out);
|
||||
|
||||
code = inflateEnd(&strm);
|
||||
if (code != Z_OK)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 7, "Failed to uninitialize zlib inflate with error #" + Str_8::FromNum(code) + ".");
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (UInt_32 i = 0, o = 0; i < bufferSize; i += scanLineF, o += scanline)
|
||||
{
|
||||
UInt_8 fCode = buffer[i];
|
||||
if (fCode == 0)
|
||||
PNG::FilterNone(&buffer[i + 1], &(*out)[o], bitDepth, channels, scanline);
|
||||
else if (fCode == 1)
|
||||
PNG::FilterSub(&buffer[i + 1], &(*out)[o], bitDepth, channels, scanline);
|
||||
else if (fCode == 2)
|
||||
PNG::FilterUp(&buffer[i + 1], &(*out)[o - scanline], bitDepth, channels, scanline);
|
||||
else if (fCode == 3)
|
||||
PNG::FilterAverage(&buffer[i + 1], &(*out)[o - scanline], bitDepth, channels, scanline);
|
||||
else if (fCode == 4)
|
||||
PNG::FilterPaeth(&buffer[i + 1], &(*out)[o - scanline], bitDepth, channels, scanline);
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -4,30 +4,29 @@
|
||||
namespace ehs
|
||||
{
|
||||
ImgCodec::ImgCodec()
|
||||
: hashExt(0), endianness(Endianness::LE), encodeCb(nullptr), decodeCb(nullptr)
|
||||
: hashExt(0), endianness(Endianness::LE), encoder(nullptr), decoder(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ImgCodec::ImgCodec(Str_8 id, Str_8 ext, const Endianness end,
|
||||
bool (* encodeCb)(const ImgCodec* const, Serializer<UInt_64>&, const Img*),
|
||||
bool (* decodeCb)(const ImgCodec* const, Serializer<UInt_64>&, Img*))
|
||||
: id(std::move(id)), hashExt(ext.Hash_64()), ext(std::move(ext)), endianness(end), encodeCb(encodeCb), decodeCb(decodeCb)
|
||||
ImgCodec::ImgCodec(Str_8 id, Str_8 ext, const Endianness end, EncodeImgCb encoder, DecodeImgCb decoder)
|
||||
: id(std::move(id)), hashExt(ext.Hash_64()), ext(std::move(ext)), endianness(end), encoder(encoder),
|
||||
decoder(decoder)
|
||||
{
|
||||
}
|
||||
|
||||
ImgCodec::ImgCodec(ImgCodec&& codec) noexcept
|
||||
: id(std::move(codec.id)), hashExt(codec.hashExt), ext(std::move(codec.ext)), endianness(codec.endianness),
|
||||
encodeCb(codec.encodeCb), decodeCb(codec.decodeCb)
|
||||
encoder(codec.encoder), decoder(codec.decoder)
|
||||
{
|
||||
codec.hashExt = 0;
|
||||
codec.endianness = Endianness::LE;
|
||||
codec.encodeCb = nullptr;
|
||||
codec.decodeCb = nullptr;
|
||||
codec.encoder = nullptr;
|
||||
codec.decoder = nullptr;
|
||||
}
|
||||
|
||||
ImgCodec::ImgCodec(const ImgCodec& codec)
|
||||
: id(codec.id), hashExt(codec.hashExt), ext(codec.ext), endianness(codec.endianness), encodeCb(codec.encodeCb),
|
||||
decodeCb(codec.decodeCb)
|
||||
: id(codec.id), hashExt(codec.hashExt), ext(codec.ext), endianness(codec.endianness), encoder(codec.encoder),
|
||||
decoder(codec.decoder)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,13 +39,13 @@ namespace ehs
|
||||
hashExt = codec.hashExt;
|
||||
ext = std::move(codec.ext);
|
||||
endianness = codec.endianness;
|
||||
encodeCb = codec.encodeCb;
|
||||
decodeCb = codec.decodeCb;
|
||||
encoder = codec.encoder;
|
||||
decoder = codec.decoder;
|
||||
|
||||
codec.hashExt = 0;
|
||||
codec.endianness = Endianness::LE;
|
||||
codec.encodeCb = nullptr;
|
||||
codec.decodeCb = nullptr;
|
||||
codec.encoder = nullptr;
|
||||
codec.decoder = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -60,8 +59,8 @@ namespace ehs
|
||||
hashExt = codec.hashExt;
|
||||
ext = codec.ext;
|
||||
endianness = codec.endianness;
|
||||
encodeCb = codec.encodeCb;
|
||||
decodeCb = codec.decodeCb;
|
||||
encoder = codec.encoder;
|
||||
decoder = codec.decoder;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -88,23 +87,23 @@ namespace ehs
|
||||
|
||||
bool ImgCodec::Encode(Serializer<UInt_64>& out, const Img* in) const
|
||||
{
|
||||
if (!encodeCb)
|
||||
if (!encoder)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Encoding is not supported for the " + id + " format.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Encoding is not supported for the " + id + " format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return encodeCb(this, out, in);
|
||||
return encoder(this, out, in);
|
||||
}
|
||||
|
||||
bool ImgCodec::Decode(Serializer<UInt_64>& in, Img* out) const
|
||||
{
|
||||
if (!decodeCb)
|
||||
if (!decoder)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Decoding is not supported for the " + id + " format.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Decoding is not supported for the " + id + " format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return decodeCb(this, in, out);
|
||||
return decoder(this, in, out);
|
||||
}
|
||||
}
|
@@ -23,7 +23,7 @@ namespace ehs
|
||||
Array<Byte, UInt_64> seq = data.ReadArray<Byte, UInt_64>(8);
|
||||
if (seq != pngSeq)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "File at file path, \"" + filePath + "\", is not a valid PNG file.");
|
||||
EHS_LOG_INT(LogType::ERR, 0, "File at file path, \"" + filePath + "\", is not a valid PNG file.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "ehs/io/model/AnimBone.h"
|
||||
#include "ehs/io/mdl/AnimBone.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "ehs/io/model/Animation.h"
|
||||
#include "ehs/io/mdl/Animation.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "ehs/io/model/Bone.h"
|
||||
#include "ehs/io/mdl/Bone.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "ehs/io/model/KeyFrame.h"
|
||||
#include "ehs/io/mdl/KeyFrame.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@@ -1,54 +1,102 @@
|
||||
#include "ehs/io/model/Model.h"
|
||||
#include "ehs/io/mdl/Mdl.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Model::Model()
|
||||
: hashId(0)
|
||||
Array<MdlCodec> Mdl::codecs;
|
||||
|
||||
bool Mdl::HasCodec(const UInt_64 hashExt)
|
||||
{
|
||||
AddType("Model");
|
||||
for (UInt_64 i = 0; i < codecs.Size(); ++i)
|
||||
if (codecs[i].GetHashExt() == hashExt)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Model::Model(const Str_8& filePath)
|
||||
bool Mdl::HasCodec(const Str_8& ext)
|
||||
{
|
||||
AddType("Model");
|
||||
return HasCodec(ext.Hash_64());
|
||||
}
|
||||
|
||||
bool Mdl::AddCodec(MdlCodec codec)
|
||||
{
|
||||
if (HasCodec(codec.GetHashExt()))
|
||||
return false;
|
||||
|
||||
codecs.Push(std::move(codec));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const MdlCodec* Mdl::GetCodec(const UInt_64 hashExt)
|
||||
{
|
||||
for (UInt_64 i = 0; i < codecs.Size(); ++i)
|
||||
if (codecs[i].GetHashExt() == hashExt)
|
||||
return &codecs[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MdlCodec* Mdl::GetCodec(const Str_8& ext)
|
||||
{
|
||||
return GetCodec(ext.Hash_64());
|
||||
}
|
||||
|
||||
Mdl::Mdl()
|
||||
: hashId(0)
|
||||
{
|
||||
AddType("Mdl");
|
||||
}
|
||||
|
||||
Mdl::Mdl(const Str_8& filePath)
|
||||
{
|
||||
AddType("Mdl");
|
||||
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
|
||||
Str_8 ext = file.GetExtension();
|
||||
hashId = file.GetName().Hash_64();
|
||||
id = file.GetName();
|
||||
|
||||
if (file.GetExtension() == "ehm")
|
||||
const MdlCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
FromEHM(file);
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
|
||||
|
||||
file.Release();
|
||||
|
||||
codec->Decode(data, this);
|
||||
}
|
||||
|
||||
Model::Model(Str_8 id, Array<Mesh> meshes, Bone skeleton, Array<Animation> animations)
|
||||
Mdl::Mdl(Str_8 id, Array<Mesh> meshes, Bone skeleton, Array<Animation> animations)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes), skeleton((Bone&&)skeleton),
|
||||
animations((Array<Animation>&&)animations)
|
||||
{
|
||||
AddType("Model");
|
||||
AddType("Mdl");
|
||||
}
|
||||
|
||||
Model::Model(Str_8 id, Array<Mesh> meshes, Bone skeleton)
|
||||
Mdl::Mdl(Str_8 id, Array<Mesh> meshes, Bone skeleton)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes), skeleton((Bone&&)skeleton)
|
||||
{
|
||||
AddType("Model");
|
||||
AddType("Mdl");
|
||||
}
|
||||
|
||||
Model::Model(Str_8 id, Array<Mesh> meshes)
|
||||
Mdl::Mdl(Str_8 id, Array<Mesh> meshes)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes)
|
||||
{
|
||||
AddType("Model");
|
||||
AddType("Mdl");
|
||||
}
|
||||
|
||||
Model::Model(Model&& model) noexcept
|
||||
Mdl::Mdl(Mdl&& model) noexcept
|
||||
: BaseObj((BaseObj&&)model), hashId(model.hashId), id((Str_8&&)model.id), meshes((Array<Mesh>&&)model.meshes),
|
||||
skeleton((Bone&&)model.skeleton), animations((Array<Animation>&&)model.animations)
|
||||
{
|
||||
}
|
||||
|
||||
Model& Model::operator=(Model&& model) noexcept
|
||||
Mdl& Mdl::operator=(Mdl&& model) noexcept
|
||||
{
|
||||
if (this == &model)
|
||||
return *this;
|
||||
@@ -66,40 +114,40 @@ namespace ehs
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Model::Release()
|
||||
void Mdl::Release()
|
||||
{
|
||||
meshes.Clear();
|
||||
skeleton = {};
|
||||
animations.Clear();
|
||||
}
|
||||
|
||||
UInt_64 Model::GetHashId() const
|
||||
UInt_64 Mdl::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void Model::SetId(Str_8 newId)
|
||||
void Mdl::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = (Str_8&&)newId;
|
||||
}
|
||||
|
||||
Str_8 Model::GetId() const
|
||||
Str_8 Mdl::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
const Array<Mesh>& Model::GetMeshes() const
|
||||
const Array<Mesh>& Mdl::GetMeshes() const
|
||||
{
|
||||
return meshes;
|
||||
}
|
||||
|
||||
Array<Mesh>& Model::GetMeshes()
|
||||
Array<Mesh>& Mdl::GetMeshes()
|
||||
{
|
||||
return meshes;
|
||||
}
|
||||
|
||||
Mesh* Model::GetMesh(const UInt_64 inHashId)
|
||||
Mesh* Mdl::GetMesh(const UInt_64 inHashId)
|
||||
{
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
if (meshes[i].GetHashId() == inHashId)
|
||||
@@ -108,22 +156,22 @@ namespace ehs
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mesh* Model::GetMesh(const Str_8& inId)
|
||||
Mesh* Mdl::GetMesh(const Str_8& inId)
|
||||
{
|
||||
return GetMesh(inId.Hash_64());
|
||||
}
|
||||
|
||||
const Bone& Model::GetSkeleton() const
|
||||
const Bone& Mdl::GetSkeleton() const
|
||||
{
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
Bone& Model::GetSkeleton()
|
||||
Bone& Mdl::GetSkeleton()
|
||||
{
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
Animation* Model::GetAnimation(const UInt_64 inHashId)
|
||||
Animation* Mdl::GetAnimation(const UInt_64 inHashId)
|
||||
{
|
||||
for (UInt_64 i = 0; i < animations.Size(); ++i)
|
||||
if (animations[i].GetHashId() == inHashId)
|
||||
@@ -132,39 +180,47 @@ namespace ehs
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Array<Animation>& Model::GetAnimations() const
|
||||
const Array<Animation>& Mdl::GetAnimations() const
|
||||
{
|
||||
return animations;
|
||||
}
|
||||
|
||||
Array<Animation>& Model::GetAnimations()
|
||||
Array<Animation>& Mdl::GetAnimations()
|
||||
{
|
||||
return animations;
|
||||
}
|
||||
|
||||
void Model::Calculate()
|
||||
void Mdl::Calculate()
|
||||
{
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
meshes[i].Calculate();
|
||||
}
|
||||
|
||||
void Model::Export(const Str_8& filePath, const ModelEncoding encoding)
|
||||
bool Mdl::Export(const Str_8& filePath) const
|
||||
{
|
||||
File file(filePath, Mode::WRITE, Disposition::OPEN_PERSISTENT);
|
||||
Str_8 ext = File::ParseExt_8(filePath);
|
||||
|
||||
switch (encoding)
|
||||
const MdlCodec* codec = GetCodec(ext);
|
||||
if (!codec)
|
||||
{
|
||||
case ModelEncoding::EHM:
|
||||
{
|
||||
ToEHM(file);
|
||||
break;
|
||||
}
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Codec not found for file extension, \"" + ext + "\".");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serializer<UInt_64> result;
|
||||
if (!codec->Encode(result, this))
|
||||
return false;
|
||||
|
||||
File file(filePath, Mode::WRITE, Disposition::CREATE_PERSISTENT);
|
||||
file.WriteSerializer_64(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Model::ToEHM(File& file)
|
||||
bool EncodeEHM(const MdlCodec* const codec, Serializer<UInt_64>& data, const Mdl* const mdl)
|
||||
{
|
||||
Serializer<UInt_64> data(Endianness::LE);
|
||||
const Array<Mesh>& meshes = mdl->GetMeshes();
|
||||
|
||||
data.WriteVersion({1, 0, 0});
|
||||
data.Write<UInt_64>(meshes.Size());
|
||||
|
||||
@@ -184,24 +240,23 @@ namespace ehs
|
||||
}
|
||||
}
|
||||
|
||||
file.WriteSerializer_64(data);
|
||||
file.Truncate(data.Size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Model::FromEHM(File& file)
|
||||
bool DecodeEHM(const MdlCodec* const codec, Serializer<UInt_64>& data, Mdl* const mdl)
|
||||
{
|
||||
Serializer<UInt_64> data = file.ReadSerializer_64(Endianness::LE, file.Size());
|
||||
|
||||
Version ver = data.ReadVersion();
|
||||
if (ver != Version(1, 0, 0))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Cannot decode EHM file version " + Str_8::FromNum(ver.major) + "." +
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Cannot decode EHM file version " + Str_8::FromNum(ver.major) + "." +
|
||||
Str_8::FromNum(ver.minor) + "." + Str_8::FromNum(ver.patch) +
|
||||
", must be version 0.0.0.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
Array<Mesh>& meshes = mdl->GetMeshes();
|
||||
meshes.Resize(data.Read<UInt_64>());
|
||||
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
{
|
||||
meshes[i].SetId(data.ReadStr<Char_8, UInt_64>());
|
||||
@@ -220,6 +275,7 @@ namespace ehs
|
||||
|
||||
meshes[i].SetIndices(data.ReadArray<UInt_32, UInt_64>());
|
||||
|
||||
Bone& skeleton = mdl->GetSkeleton();
|
||||
UInt_8 boneCount = data.Read<UInt_8>();
|
||||
for (UInt_8 b = 0; b < boneCount; ++b)
|
||||
{
|
||||
@@ -236,15 +292,17 @@ namespace ehs
|
||||
Bone* parent = skeleton.GetBone(parentId);
|
||||
if (!parent)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Invalid bone order.");
|
||||
return;
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Invalid bone order.");
|
||||
return false;
|
||||
}
|
||||
|
||||
parent->AddBone({name, b, localBindTrans, invBindTrans});
|
||||
}
|
||||
}
|
||||
|
||||
animations = Array<Animation>(data.Read<UInt_64>());
|
||||
Array<Animation>& animations = mdl->GetAnimations();
|
||||
animations.Resize(data.Read<UInt_64>());
|
||||
|
||||
for (UInt_64 a = 0; a < animations.Size(); ++a)
|
||||
{
|
||||
Str_8 animId = data.ReadStr<Char_8, UInt_64>();
|
||||
@@ -271,5 +329,7 @@ namespace ehs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
108
src/io/model/MdlCodec.cpp
Normal file
108
src/io/model/MdlCodec.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "ehs/io/mdl/MdlCodec.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
MdlCodec::MdlCodec()
|
||||
: hashExt(0), endianness(Endianness::LE), encoder(nullptr), decoder(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MdlCodec::MdlCodec(Str_8 id, Str_8 ext, const Endianness end, EnocdeMdlCb encoder, DecodeMdlCb decoder)
|
||||
: id(std::move(id)), hashExt(ext.Hash_64()), ext(std::move(ext)), endianness(end), encoder(encoder),
|
||||
decoder(decoder)
|
||||
{
|
||||
}
|
||||
|
||||
MdlCodec::MdlCodec(MdlCodec&& codec) noexcept
|
||||
: id(std::move(codec.id)), hashExt(codec.hashExt), ext(std::move(codec.ext)), endianness(codec.endianness),
|
||||
encoder(codec.encoder), decoder(codec.decoder)
|
||||
{
|
||||
codec.hashExt = 0;
|
||||
codec.endianness = Endianness::LE;
|
||||
codec.encoder = nullptr;
|
||||
codec.decoder = nullptr;
|
||||
}
|
||||
|
||||
MdlCodec::MdlCodec(const MdlCodec& codec)
|
||||
: id(codec.id), hashExt(codec.hashExt), ext(codec.ext), endianness(codec.endianness), encoder(codec.encoder),
|
||||
decoder(codec.decoder)
|
||||
{
|
||||
}
|
||||
|
||||
MdlCodec& MdlCodec::operator=(MdlCodec&& codec) noexcept
|
||||
{
|
||||
if (this == &codec)
|
||||
return *this;
|
||||
|
||||
id = std::move(codec.id);
|
||||
hashExt = codec.hashExt;
|
||||
ext = std::move(codec.ext);
|
||||
endianness = codec.endianness;
|
||||
encoder = codec.encoder;
|
||||
decoder = codec.decoder;
|
||||
|
||||
codec.hashExt = 0;
|
||||
codec.endianness = Endianness::LE;
|
||||
codec.encoder = nullptr;
|
||||
codec.decoder = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MdlCodec& MdlCodec::operator=(const MdlCodec& codec)
|
||||
{
|
||||
if (this == &codec)
|
||||
return *this;
|
||||
|
||||
id = codec.id;
|
||||
hashExt = codec.hashExt;
|
||||
ext = codec.ext;
|
||||
endianness = codec.endianness;
|
||||
encoder = codec.encoder;
|
||||
decoder = codec.decoder;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Str_8 MdlCodec::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
UInt_64 MdlCodec::GetHashExt() const
|
||||
{
|
||||
return hashExt;
|
||||
}
|
||||
|
||||
Str_8 MdlCodec::GetExt() const
|
||||
{
|
||||
return ext;
|
||||
}
|
||||
|
||||
Endianness MdlCodec::GetEndianness() const
|
||||
{
|
||||
return endianness;
|
||||
}
|
||||
|
||||
bool MdlCodec::Encode(Serializer<UInt_64>& out, const Mdl* in) const
|
||||
{
|
||||
if (!encoder)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Encoding is not supported for the " + id + " format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return encoder(this, out, in);
|
||||
}
|
||||
|
||||
bool MdlCodec::Decode(Serializer<UInt_64>& in, Mdl* out) const
|
||||
{
|
||||
if (!decoder)
|
||||
{
|
||||
EHS_LOG_INT(LogType::ERR, 0, "Decoding is not supported for the " + id + " format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return decoder(this, in, out);
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
#include "ehs/io/model/Mesh.h"
|
||||
#include "ehs/io/mdl/Mesh.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
@@ -29,7 +29,7 @@ namespace ehs
|
||||
}
|
||||
|
||||
Mesh::Mesh(const Mesh& mesh)
|
||||
: BaseObj((BaseObj&&)mesh), hashId(mesh.hashId), id(mesh.id), vertices(mesh.vertices), indices(mesh.indices)
|
||||
: BaseObj(mesh), hashId(mesh.hashId), id(mesh.id), vertices(mesh.vertices), indices(mesh.indices)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "ehs/io/model/PropertyChange.h"
|
||||
#include "ehs/io/mdl/PropertyChange.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user