mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_ARRAYWRAPPER_H_
|
||||
#define INCLUDE_KYTY_CORE_ARRAYWRAPPER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
#include <initializer_list> // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
template <class Type, int Num>
|
||||
class Array final
|
||||
{
|
||||
public:
|
||||
Array() = default;
|
||||
~Array() = default;
|
||||
|
||||
KYTY_CLASS_DEFAULT_COPY(Array);
|
||||
|
||||
Array(std::initializer_list<Type> list) noexcept: m_ptr {}
|
||||
{
|
||||
int index = 0;
|
||||
for (const Type& e: list)
|
||||
{
|
||||
(*this)[index++] = e;
|
||||
}
|
||||
}
|
||||
|
||||
const Type& operator[](int index) const
|
||||
{
|
||||
EXIT_IF(index < 0 || index >= Num);
|
||||
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
Type& operator[](int index)
|
||||
{
|
||||
EXIT_IF(index < 0 || index >= Num);
|
||||
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
operator Type const *() const { return &m_ptr[0]; }
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
operator Type*() { return &m_ptr[0]; }
|
||||
|
||||
[[nodiscard]] int Size() const { return Num; }
|
||||
|
||||
Type* GetPtr() { return m_ptr; }
|
||||
|
||||
[[nodiscard]] const Type* GetPtr() const { return m_ptr; }
|
||||
|
||||
[[nodiscard]] size_t ByteSize() const { return sizeof(Type) * Num; }
|
||||
|
||||
// void SetZero()
|
||||
// {
|
||||
// memset(m_ptr, 0, sizeof(Type) * num);
|
||||
// }
|
||||
//
|
||||
// void Memset(int fill)
|
||||
// {
|
||||
// memset(m_ptr, fill, sizeof(Type) * num);
|
||||
// }
|
||||
|
||||
using iterator = Type*;
|
||||
using const_iterator = const Type*;
|
||||
|
||||
iterator begin() { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
iterator end() { return &m_ptr[Num]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator begin() const { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator end() const { return &m_ptr[Num]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cbegin() const { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cend() const { return &m_ptr[Num]; } // NOLINT(readability-identifier-naming)
|
||||
|
||||
private:
|
||||
Type m_ptr[Num];
|
||||
};
|
||||
|
||||
template <class Type, int Num1, int Num2>
|
||||
class Array2 final
|
||||
{
|
||||
public:
|
||||
Array2() = default;
|
||||
~Array2() = default;
|
||||
|
||||
KYTY_CLASS_DEFAULT_COPY(Array2);
|
||||
|
||||
Array2(std::initializer_list<Array<Type, Num2>> list) noexcept: m_ptr {}
|
||||
{
|
||||
int index = 0;
|
||||
for (const Array<Type, Num2>& e: list)
|
||||
{
|
||||
(*this)[index++] = e;
|
||||
}
|
||||
}
|
||||
|
||||
const Array<Type, Num2>& operator[](int index) const
|
||||
{
|
||||
EXIT_IF(index < 0 || index >= Num1);
|
||||
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
Array<Type, Num2>& operator[](int index)
|
||||
{
|
||||
EXIT_IF(index < 0 || index >= Num1);
|
||||
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
operator Type const *() const { return &m_ptr[0][0]; }
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
operator Type*() { return &m_ptr[0][0]; }
|
||||
|
||||
[[nodiscard]] int Size() const { return Num1; }
|
||||
|
||||
Array<Type, Num2>* GetPtr() { return m_ptr; }
|
||||
|
||||
[[nodiscard]] const Array<Type, Num2>* GetPtr() const { return m_ptr; }
|
||||
|
||||
[[nodiscard]] size_t ByteSize() const { return sizeof(Type) * Num1 * Num2; }
|
||||
|
||||
// void SetZero()
|
||||
// {
|
||||
// memset(m_ptr, 0, sizeof(Type) * num1 * num2);
|
||||
// }
|
||||
//
|
||||
// void Memset(int fill)
|
||||
// {
|
||||
// memset(m_ptr, fill, sizeof(Type) * num1 * num2);
|
||||
// }
|
||||
|
||||
using iterator = Array<Type, Num2>*;
|
||||
using const_iterator = const Array<Type, Num2>*;
|
||||
|
||||
iterator begin() { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
iterator end() { return &m_ptr[Num1]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator begin() const { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator end() const { return &m_ptr[Num1]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cbegin() const { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cend() const { return &m_ptr[Num1]; } // NOLINT(readability-identifier-naming)
|
||||
|
||||
private:
|
||||
Array<Type, Num2> m_ptr[Num1];
|
||||
};
|
||||
|
||||
template <class Type, int Num1, int Num2, int Num3>
|
||||
class Array3
|
||||
{
|
||||
public:
|
||||
Array3() = default;
|
||||
~Array3() = default;
|
||||
|
||||
KYTY_CLASS_DEFAULT_COPY(Array3);
|
||||
|
||||
Array3(std::initializer_list<Array2<Type, Num2, Num3>> list) noexcept: m_ptr {}
|
||||
{
|
||||
int index = 0;
|
||||
for (const Array2<Type, Num2, Num3>& e: list)
|
||||
{
|
||||
(*this)[index++] = e;
|
||||
}
|
||||
}
|
||||
|
||||
const Array2<Type, Num2, Num3>& operator[](int index) const
|
||||
{
|
||||
EXIT_IF(index < 0 || index >= Num1);
|
||||
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
Array2<Type, Num2, Num3>& operator[](int index)
|
||||
{
|
||||
EXIT_IF(index < 0 || index >= Num1);
|
||||
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
operator Type const *() const { return &m_ptr[0][0][0]; }
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
operator Type*() { return &m_ptr[0][0][0]; }
|
||||
|
||||
[[nodiscard]] int Size() const { return Num1; }
|
||||
|
||||
Array2<Type, Num2, Num3>* GetPtr() { return m_ptr; }
|
||||
|
||||
[[nodiscard]] const Array2<Type, Num2, Num3>* GetPtr() const { return m_ptr; }
|
||||
|
||||
[[nodiscard]] size_t ByteSize() const { return sizeof(Type) * Num1 * Num2 * Num3; }
|
||||
|
||||
// void SetZero()
|
||||
// {
|
||||
// memset(m_ptr, 0, sizeof(Type) * num1 * num2 * num3);
|
||||
// }
|
||||
//
|
||||
// void Memset(int fill)
|
||||
// {
|
||||
// memset(m_ptr, fill, sizeof(Type) * num1 * num2 * num3);
|
||||
// }
|
||||
|
||||
using iterator = Array2<Type, Num2, Num3>*;
|
||||
using const_iterator = const Array2<Type, Num2, Num3>*;
|
||||
|
||||
iterator begin() { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
iterator end() { return &m_ptr[Num1]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator begin() const { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator end() const { return &m_ptr[Num1]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cbegin() const { return &m_ptr[0]; } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cend() const { return &m_ptr[Num1]; } // NOLINT(readability-identifier-naming)
|
||||
|
||||
private:
|
||||
Array2<Type, Num2, Num3> m_ptr[Num1];
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#define KYTY_ARRAY_NUM(a) ((int)(sizeof((a)) / sizeof((a)[0])))
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_ARRAYWRAPPER_H_ */
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_BYTEBUFFER_H_
|
||||
#define INCLUDE_KYTY_CORE_BYTEBUFFER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include <cstddef> // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
using Byte = std::byte;
|
||||
|
||||
class ByteBuffer: public Vector<Byte>
|
||||
{
|
||||
public:
|
||||
ByteBuffer() = default;
|
||||
using Vector<Byte>::Vector;
|
||||
|
||||
ByteBuffer(std::initializer_list<uint8_t> list): ByteBuffer(static_cast<uint32_t>(list.size()), false) // @suppress("Ambiguous problem")
|
||||
{
|
||||
Byte* values_ptr = GetData();
|
||||
for (const uint8_t& e: list)
|
||||
{
|
||||
*(values_ptr++) = static_cast<Byte>(e);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer(const void* buf, uint32_t size): ByteBuffer(size, false) // @suppress("Ambiguous problem")
|
||||
{
|
||||
Byte* values_ptr = GetData();
|
||||
std::memcpy(values_ptr, buf, size);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_BYTEBUFFER_H_ */
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_COMMON_H_
|
||||
#define INCLUDE_KYTY_CORE_COMMON_H_
|
||||
|
||||
#include "kyty_config.h" // IWYU pragma: export
|
||||
|
||||
#if KYTY_COMPILER != KYTY_COMPILER_MSVC
|
||||
#if __cplusplus < 201703L
|
||||
#undef __cplusplus
|
||||
#define __cplusplus 201703L
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (KYTY_COMPILER == KYTY_COMPILER_MINGW)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage,cert-dcl51-cpp,cert-dcl37-c,bugprone-reserved-identifier)
|
||||
#define __USE_MINGW_ANSI_STDIO 1
|
||||
#endif
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#define KYTY_FORCE_LINK_THIS(x) int force_link_##x = 0;
|
||||
#define KYTY_FORCE_LINK_THAT(x) \
|
||||
void force_link_function_##x() \
|
||||
{ \
|
||||
extern int force_link_##x; \
|
||||
force_link_##x = 1; \
|
||||
}
|
||||
|
||||
#define KYTY_CLASS_NO_COPY(name) \
|
||||
public: \
|
||||
name(const name&) = delete; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name& operator=(const name&) = delete; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name(name&&) noexcept = delete; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name& operator=(name&&) noexcept = delete; /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
#define KYTY_CLASS_DEFAULT_COPY(name) \
|
||||
public: \
|
||||
name(const name&) = default; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name& operator=(const name&) = default; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name(name&&) noexcept = default; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name& operator=(name&&) noexcept = default; /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
#if (KYTY_COMPILER == KYTY_COMPILER_MINGW || KYTY_COMPILER == KYTY_COMPILER_GCC)
|
||||
#define KYTY_FORMAT_PRINTF(a, b) __attribute__((format(gnu_printf, a, b)))
|
||||
#elif KYTY_COMPILER == KYTY_COMPILER_CLANG
|
||||
#define KYTY_FORMAT_PRINTF(a, b) __attribute__((format(printf, a, b)))
|
||||
#else
|
||||
#define KYTY_FORMAT_PRINTF(a, b)
|
||||
#endif
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_ANDROID
|
||||
#include <android/log.h> // IWYU pragma: export
|
||||
#define KYTY_LOG_TAG "KYTY_Tag"
|
||||
#define KYTY_LOGI(...) __android_log_print(ANDROID_LOG_INFO, KYTY_LOG_TAG, __VA_ARGS__)
|
||||
#define KYTY_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, KYTY_LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define KYTY_LOGI printf
|
||||
#define KYTY_LOGE printf
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_COMMON_H_ */
|
||||
@@ -0,0 +1,147 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_COMPRESSION_H_
|
||||
#define INCLUDE_KYTY_CORE_COMPRESSION_H_
|
||||
|
||||
#include "Kyty/Core/ByteBuffer.h"
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DateTime.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
using ZipCompressLevel = int;
|
||||
using ZstdCompressLevel = int;
|
||||
|
||||
constexpr ZipCompressLevel ZIP_NO_COMPRESSION = 0;
|
||||
constexpr ZipCompressLevel ZIP_BEST_SPEED = 1;
|
||||
constexpr ZipCompressLevel ZIP_DEFAULT_LEVEL = 6;
|
||||
constexpr ZipCompressLevel ZIP_BEST_COMPRESSION = 9;
|
||||
|
||||
constexpr ZstdCompressLevel ZSTD_BEST_SPEED = 1;
|
||||
constexpr ZstdCompressLevel ZSTD_DEFAULT_LEVEL = 3;
|
||||
constexpr ZstdCompressLevel ZSTD_BEST_COMPRESSION = 22;
|
||||
|
||||
ByteBuffer CompressZstd(const uint8_t* buf, uint32_t length, int level = ZSTD_DEFAULT_LEVEL);
|
||||
ByteBuffer CompressZstd(const ByteBuffer& buf, int level = ZSTD_DEFAULT_LEVEL);
|
||||
ByteBuffer CompressZstd(const String& str, int level = ZSTD_DEFAULT_LEVEL);
|
||||
|
||||
ByteBuffer DecompressZstd(const uint8_t* buf, uint32_t length);
|
||||
ByteBuffer DecompressZstd(const ByteBuffer& buf);
|
||||
String DecompressZstdStr(const uint8_t* buf, uint32_t length);
|
||||
String DecompressZstdStr(const ByteBuffer& buf);
|
||||
|
||||
ByteBuffer CompressLzma(const uint8_t* buf, uint32_t length);
|
||||
ByteBuffer CompressLzma(const ByteBuffer& buf);
|
||||
ByteBuffer CompressLzma(const String& str);
|
||||
|
||||
ByteBuffer DecompressLzma(const uint8_t* buf, uint32_t length);
|
||||
ByteBuffer DecompressLzma(const ByteBuffer& buf);
|
||||
String DecompressLzmaStr(const uint8_t* buf, uint32_t length);
|
||||
String DecompressLzmaStr(const ByteBuffer& buf);
|
||||
|
||||
ByteBuffer CompressZip(const uint8_t* buf, uint32_t length, ZipCompressLevel level = ZIP_DEFAULT_LEVEL);
|
||||
ByteBuffer CompressZip(const ByteBuffer& buf, ZipCompressLevel level = ZIP_DEFAULT_LEVEL);
|
||||
ByteBuffer CompressZip(const String& str, ZipCompressLevel level = ZIP_DEFAULT_LEVEL);
|
||||
|
||||
ByteBuffer DecompressZip(const uint8_t* buf, uint32_t length);
|
||||
ByteBuffer DecompressZip(const ByteBuffer& buf);
|
||||
String DecompressZipStr(const uint8_t* buf, uint32_t length);
|
||||
String DecompressZipStr(const ByteBuffer& buf);
|
||||
|
||||
ByteBuffer CompressLzf(const uint8_t* buf, uint32_t length);
|
||||
ByteBuffer CompressLzf(const ByteBuffer& buf);
|
||||
ByteBuffer CompressLzf(const String& str);
|
||||
|
||||
ByteBuffer DecompressLzf(const uint8_t* buf, uint32_t length);
|
||||
ByteBuffer DecompressLzf(const ByteBuffer& buf);
|
||||
String DecompressLzfStr(const uint8_t* buf, uint32_t length);
|
||||
String DecompressLzfStr(const ByteBuffer& buf);
|
||||
|
||||
struct ZipFileStat
|
||||
{
|
||||
uint32_t m_file_index;
|
||||
// uint32_t m_central_dir_ofs;
|
||||
// uint16_t m_version_made_by;
|
||||
// uint16_t m_version_needed;
|
||||
// uint16_t m_bit_flag;
|
||||
// uint16_t m_method;
|
||||
DateTime m_time;
|
||||
uint32_t m_crc32;
|
||||
uint64_t m_comp_size;
|
||||
uint64_t m_uncomp_size;
|
||||
// uint16_t m_internal_attr;
|
||||
// uint32_t m_external_attr;
|
||||
// uint64_t m_local_header_ofs;
|
||||
// uint32_t m_comment_size;
|
||||
String m_filename;
|
||||
String m_comment;
|
||||
};
|
||||
|
||||
struct ZipPrivate;
|
||||
|
||||
class ZipReader
|
||||
{
|
||||
public:
|
||||
ZipReader() = default;
|
||||
virtual ~ZipReader();
|
||||
|
||||
bool Open(const String& file_name);
|
||||
bool Open(const ByteBuffer& buf);
|
||||
bool Open(uint8_t* mem, uint32_t size);
|
||||
|
||||
void Close();
|
||||
|
||||
// Returns the total number of files in the archive.
|
||||
int GetNumFiles();
|
||||
|
||||
// Returns detailed information about an archive file entry.
|
||||
bool GetFileStat(int file_index, ZipFileStat* out_stat);
|
||||
|
||||
// Determines if an archive file entry is a directory entry.
|
||||
bool IsFileDirectory(int file_index);
|
||||
bool IsFileEncrypted(int file_index);
|
||||
|
||||
// Retrieves the filename of an archive file entry.
|
||||
String GetFileName(int file_index);
|
||||
|
||||
// Attempts to locates a file in the archive's central directory.
|
||||
// Returns -1 if the file cannot be found.
|
||||
int FindFile(const String& name, const String& comment = U"");
|
||||
|
||||
// Extracts a archive file to a memory buffer
|
||||
ByteBuffer ExtractFile(int file_index);
|
||||
ByteBuffer ExtractFile(const String& name);
|
||||
|
||||
friend class ZipWriter;
|
||||
|
||||
KYTY_CLASS_NO_COPY(ZipReader);
|
||||
|
||||
private:
|
||||
ZipPrivate* m_p = nullptr;
|
||||
};
|
||||
|
||||
class ZipWriter
|
||||
{
|
||||
public:
|
||||
ZipWriter() = default;
|
||||
virtual ~ZipWriter();
|
||||
|
||||
bool Create(const String& file_name);
|
||||
|
||||
void Close();
|
||||
|
||||
bool AddFile(const String& file_name, const ByteBuffer& buf, ZipCompressLevel level = ZIP_DEFAULT_LEVEL);
|
||||
bool AddFile(const String& file_name, const uint8_t* buf, uint32_t size, ZipCompressLevel level = ZIP_DEFAULT_LEVEL);
|
||||
bool AddFileFromFile(const String& file_name, const String& from_file, ZipCompressLevel level = ZIP_DEFAULT_LEVEL);
|
||||
bool AddFileFromReader(const String& file_name, ZipReader* from_reader, int file_index);
|
||||
|
||||
bool AddDir(const String& dir_name);
|
||||
|
||||
KYTY_CLASS_NO_COPY(ZipWriter);
|
||||
|
||||
private:
|
||||
ZipPrivate* m_p = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_COMPRESSION_H_ */
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_CORE_H_
|
||||
#define INCLUDE_KYTY_CORE_CORE_H_
|
||||
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Core);
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_CORE_H_ */
|
||||
@@ -0,0 +1,164 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_DATABASE_H_
|
||||
#define INCLUDE_KYTY_CORE_DATABASE_H_
|
||||
|
||||
#include "Kyty/Core/ByteBuffer.h"
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
namespace Kyty::Core::Database {
|
||||
|
||||
struct StatementPrivate;
|
||||
struct ConnectionPrivate;
|
||||
|
||||
void Init();
|
||||
|
||||
class Statement
|
||||
{
|
||||
public:
|
||||
enum class State
|
||||
{
|
||||
Done,
|
||||
Row,
|
||||
Error
|
||||
};
|
||||
enum class Type
|
||||
{
|
||||
Integer,
|
||||
Float,
|
||||
Text,
|
||||
Blob,
|
||||
Null
|
||||
};
|
||||
|
||||
State Step();
|
||||
|
||||
void Reset();
|
||||
|
||||
void ClearBindings();
|
||||
void BindBlob(const char* name, const ByteBuffer& blob) { BindBlob(GetIndex(name), blob); }
|
||||
void BindBlob(const String& name, const ByteBuffer& blob) { BindBlob(GetIndex(name), blob); }
|
||||
void BindBlob(int index, const ByteBuffer& blob);
|
||||
void BindDouble(const char* name, double d) { BindDouble(GetIndex(name), d); }
|
||||
void BindDouble(const String& name, double d) { BindDouble(GetIndex(name), d); }
|
||||
void BindDouble(int index, double d);
|
||||
void BindInt(const char* name, int i) { BindInt(GetIndex(name), i); }
|
||||
void BindInt(const String& name, int i) { BindInt(GetIndex(name), i); }
|
||||
void BindInt(int index, int i);
|
||||
void BindInt64(const char* name, int64_t i) { BindInt64(GetIndex(name), i); }
|
||||
void BindInt64(const String& name, int64_t i) { BindInt64(GetIndex(name), i); }
|
||||
void BindInt64(int index, int64_t i);
|
||||
void BindString(const char* name, const String& str) { BindString(GetIndex(name), str); }
|
||||
void BindString(const String& name, const String& str) { BindString(GetIndex(name), str); }
|
||||
void BindString(int index, const String& str);
|
||||
void BindString(const char* name, const char* str) { BindString(GetIndex(name), str); }
|
||||
void BindString(const String& name, const char* str) { BindString(GetIndex(name), str); }
|
||||
void BindString(int index, const char* str);
|
||||
void BindNull(const char* name) { BindNull(GetIndex(name)); }
|
||||
void BindNull(const String& name) { BindNull(GetIndex(name)); }
|
||||
void BindNull(int index);
|
||||
int GetIndex(const char* name);
|
||||
int GetIndex(const String& name);
|
||||
|
||||
int GetColumnCount();
|
||||
const char* GetColumnName(int index);
|
||||
const char* GetColumnNameDatabase(int index);
|
||||
const char* GetColumnNameTable(int index);
|
||||
const char* GetColumnNameField(int index);
|
||||
ByteBuffer GetColumnBlob(int index);
|
||||
double GetColumnDouble(int index);
|
||||
int GetColumnInt(int index);
|
||||
int64_t GetColumnInt64(int index);
|
||||
String GetColumnString(int index);
|
||||
Type GetColumnType(int index);
|
||||
|
||||
void DbgTest();
|
||||
|
||||
KYTY_CLASS_NO_COPY(Statement);
|
||||
|
||||
friend class Connection;
|
||||
|
||||
protected:
|
||||
virtual ~Statement();
|
||||
explicit Statement(ConnectionPrivate* c);
|
||||
|
||||
private:
|
||||
StatementPrivate* m_p;
|
||||
};
|
||||
|
||||
class Connection
|
||||
{
|
||||
public:
|
||||
enum class Mode
|
||||
{
|
||||
ReadOnly,
|
||||
ReadWrite
|
||||
};
|
||||
struct ExecRow
|
||||
{
|
||||
StringList names;
|
||||
StringList values;
|
||||
};
|
||||
class ExecResult: public Vector<ExecRow>
|
||||
{
|
||||
public:
|
||||
using Vector<ExecRow>::Vector;
|
||||
using Vector<ExecRow>::At;
|
||||
[[nodiscard]] bool CheckSize(uint32_t columns_num, uint32_t rows_num) const
|
||||
{
|
||||
return Size() == rows_num && (rows_num != 0u ? At(0).values.Size() == columns_num : false);
|
||||
}
|
||||
[[nodiscard]] const String& At(uint32_t column, uint32_t row) const { return At(row).values.At(column); }
|
||||
};
|
||||
|
||||
Connection();
|
||||
virtual ~Connection();
|
||||
|
||||
bool CreateInMemory();
|
||||
bool Create(const String& file_name);
|
||||
bool Open(const String& file_name, Mode mode);
|
||||
void Close();
|
||||
|
||||
void CopyTo(Connection* db);
|
||||
|
||||
void SetPassword(const String& password, int legacy);
|
||||
[[nodiscard]] ByteBuffer GetSalt() const;
|
||||
[[nodiscard]] ByteBuffer GetKey() const;
|
||||
void SetKey(const ByteBuffer& key);
|
||||
|
||||
[[nodiscard]] bool IsInvalid() const;
|
||||
|
||||
[[nodiscard]] bool IsError() const { return m_error; }
|
||||
[[nodiscard]] int GetErrorCode() const { return m_error_code; }
|
||||
[[nodiscard]] const String& GetErrorMsg() const { return m_error_msg; }
|
||||
[[nodiscard]] int GetExtErrorCode() const { return m_ext_error_code; }
|
||||
|
||||
Statement* Prepare(const char* sql_text);
|
||||
Statement* Prepare(const String& sql_text) { return Prepare(sql_text.C_Str()); }
|
||||
void CloseAllStatements();
|
||||
ExecResult Exec(const char* sql_text);
|
||||
ExecResult Exec(const String& sql_text) { return Exec(sql_text.C_Str()); }
|
||||
|
||||
void BeginTransaction();
|
||||
void EndTransaction();
|
||||
void Vacuum();
|
||||
|
||||
int64_t GetLastInsertRowid();
|
||||
int Changes();
|
||||
|
||||
KYTY_CLASS_NO_COPY(Connection);
|
||||
|
||||
friend struct ConnectionPrivate;
|
||||
|
||||
private:
|
||||
bool m_error {false};
|
||||
int m_error_code {};
|
||||
int m_ext_error_code {};
|
||||
String m_error_msg;
|
||||
|
||||
ConnectionPrivate* m_p {nullptr};
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core::Database
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_DATABASE_H_ */
|
||||
@@ -0,0 +1,198 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_DATETIME_H_
|
||||
#define INCLUDE_KYTY_CORE_DATETIME_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Language.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
using jd_t = int32_t;
|
||||
|
||||
constexpr jd_t DATE_JD_INVALID = (INT32_MIN);
|
||||
constexpr int TIME_MS_INVALID = (-1);
|
||||
constexpr int TIME_MS_IN_DAY = (24 * 3600 * 1000);
|
||||
|
||||
constexpr int MONTH_JANUARY = 1;
|
||||
constexpr int MONTH_FEBRUARY = 2;
|
||||
constexpr int MONTH_MARCH = 3;
|
||||
constexpr int MONTH_APRIL = 4;
|
||||
constexpr int MONTH_MAY = 5;
|
||||
constexpr int MONTH_JUNE = 6;
|
||||
constexpr int MONTH_JULY = 7;
|
||||
constexpr int MONTH_AUGUST = 8;
|
||||
constexpr int MONTH_SEPTEMBER = 9;
|
||||
constexpr int MONTH_OCTOBER = 10;
|
||||
constexpr int MONTH_NOVEMBER = 11;
|
||||
constexpr int MONTH_DECEMBER = 12;
|
||||
|
||||
class Date final
|
||||
{
|
||||
public:
|
||||
Date() = default;
|
||||
explicit Date(jd_t d): m_jd(d) {}
|
||||
Date(const Date& d) = default;
|
||||
Date(Date&& d) noexcept = default;
|
||||
Date(int year, int month, int day); // month in [1...12], day in [1...31]
|
||||
~Date() = default;
|
||||
|
||||
static Date FromSystem();
|
||||
static Date FromSystemUTC();
|
||||
static Date FromMacros(const String& date);
|
||||
|
||||
void Set(int year, int month, int day);
|
||||
void Set(jd_t jd) { this->m_jd = jd; }
|
||||
void Get(int* year, int* month, int* day) const;
|
||||
|
||||
[[nodiscard]] bool IsInvalid() const { return m_jd == DATE_JD_INVALID; }
|
||||
[[nodiscard]] int DaysInMonth() const;
|
||||
[[nodiscard]] int DaysInYear() const;
|
||||
[[nodiscard]] bool IsLeapYear() const;
|
||||
[[nodiscard]] int Year() const;
|
||||
[[nodiscard]] int Month() const;
|
||||
[[nodiscard]] int Day() const;
|
||||
[[nodiscard]] jd_t JulianDay() const { return m_jd; }
|
||||
[[nodiscard]] int DayOfWeek() const;
|
||||
[[nodiscard]] int DayOfYear() const;
|
||||
[[nodiscard]] int QuarterOfYear() const;
|
||||
|
||||
String ToString(const char* format = "YYYY.MM.DD", LanguageId lang_id = LanguageId::English) const;
|
||||
|
||||
static bool IsValid(int year, int month, int day);
|
||||
static int DaysInMonth(int month);
|
||||
static int DaysInYear(int year);
|
||||
static bool IsLeapYear(int year);
|
||||
|
||||
bool operator==(const Date& other) const { return m_jd == other.m_jd; }
|
||||
bool operator!=(const Date& other) const { return m_jd != other.m_jd; }
|
||||
bool operator<(const Date& other) const { return m_jd < other.m_jd; }
|
||||
bool operator<=(const Date& other) const { return m_jd <= other.m_jd; }
|
||||
bool operator>(const Date& other) const { return m_jd > other.m_jd; }
|
||||
bool operator>=(const Date& other) const { return m_jd >= other.m_jd; }
|
||||
|
||||
Date& operator=(const Date& other) = default;
|
||||
Date& operator=(Date&& other) noexcept = default;
|
||||
Date operator+(int days) const { return Date(m_jd + days); }
|
||||
Date operator-(int days) const { return Date(m_jd - days); }
|
||||
Date operator+=(int days)
|
||||
{
|
||||
m_jd += days;
|
||||
return *this;
|
||||
}
|
||||
Date operator-=(int days)
|
||||
{
|
||||
m_jd -= days;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
jd_t m_jd {DATE_JD_INVALID};
|
||||
};
|
||||
|
||||
class Time final
|
||||
{
|
||||
public:
|
||||
Time() = default;
|
||||
explicit Time(int msec): m_ms(msec)
|
||||
{
|
||||
if (m_ms < 0 || m_ms >= TIME_MS_IN_DAY)
|
||||
{
|
||||
m_ms = TIME_MS_INVALID;
|
||||
}
|
||||
}
|
||||
Time(const Time& t) = default;
|
||||
Time(Time&& t) noexcept = default;
|
||||
Time(int hour24, int minute, int second, int msec = 0);
|
||||
~Time() = default;
|
||||
|
||||
static Time FromSystem();
|
||||
static Time FromSystemUTC();
|
||||
|
||||
void Set(int hour24, int minute, int second, int msec = 0);
|
||||
void Set(int msec) { m_ms = msec; }
|
||||
void Get(int* hour24, int* minute, int* second, int* msec = nullptr) const;
|
||||
|
||||
[[nodiscard]] bool IsInvalid() const { return m_ms < 0 || m_ms >= TIME_MS_IN_DAY; }
|
||||
[[nodiscard]] int Hour12() const;
|
||||
[[nodiscard]] int Hour24() const;
|
||||
[[nodiscard]] bool IsAM() const;
|
||||
[[nodiscard]] bool IsPM() const;
|
||||
[[nodiscard]] int Minute() const;
|
||||
[[nodiscard]] int Second() const;
|
||||
[[nodiscard]] int Msec() const;
|
||||
[[nodiscard]] int MsecTotal() const { return m_ms; }
|
||||
|
||||
String ToString(const char* format = "HH24:MI:SS") const;
|
||||
|
||||
static bool IsValid(int hour, int minute, int second, int msec = 0);
|
||||
|
||||
bool operator==(const Time& other) const { return m_ms == other.m_ms; }
|
||||
bool operator!=(const Time& other) const { return m_ms != other.m_ms; }
|
||||
bool operator<(const Time& other) const { return m_ms < other.m_ms; }
|
||||
bool operator<=(const Time& other) const { return m_ms <= other.m_ms; }
|
||||
bool operator>(const Time& other) const { return m_ms > other.m_ms; }
|
||||
bool operator>=(const Time& other) const { return m_ms >= other.m_ms; }
|
||||
|
||||
Time& operator=(const Time& other) = default;
|
||||
Time& operator=(Time&& other) noexcept = default;
|
||||
Time operator+(int secs) const;
|
||||
Time operator-(int secs) const;
|
||||
Time operator+=(int secs);
|
||||
Time operator-=(int secs);
|
||||
|
||||
private:
|
||||
int m_ms {TIME_MS_INVALID};
|
||||
};
|
||||
|
||||
class DateTime final
|
||||
{
|
||||
public:
|
||||
DateTime() = default;
|
||||
explicit DateTime(const Date& d): m_date(d) {}
|
||||
explicit DateTime(const Time& t): m_time(t) {}
|
||||
DateTime(const Date& d, const Time& t): m_date(d), m_time(t) {}
|
||||
DateTime(const Time& t, const Date& d): m_date(d), m_time(t) {}
|
||||
DateTime(const DateTime& dt) = default;
|
||||
DateTime(DateTime&& dt) noexcept = default;
|
||||
~DateTime() = default;
|
||||
|
||||
static DateTime FromSystem();
|
||||
static DateTime FromSystemUTC();
|
||||
|
||||
static DateTime FromSQLiteJulian(double jd);
|
||||
[[nodiscard]] double ToSQLiteJulian() const;
|
||||
[[nodiscard]] int64_t ToSQLiteJulianInt64() const;
|
||||
static DateTime FromUnix(double seconds);
|
||||
[[nodiscard]] double ToUnix() const;
|
||||
|
||||
[[nodiscard]] uint64_t DistanceMs(const DateTime& other) const;
|
||||
|
||||
[[nodiscard]] bool IsInvalid() const { return m_date.IsInvalid() || m_time.IsInvalid(); }
|
||||
|
||||
void SetDate(const Date& d) { m_date = d; }
|
||||
void SetTime(const Time& t) { m_time = t; }
|
||||
Date& GetDate() { return m_date; }
|
||||
Time& GetTime() { return m_time; }
|
||||
[[nodiscard]] const Date& GetDate() const { return m_date; }
|
||||
[[nodiscard]] const Time& GetTime() const { return m_time; }
|
||||
|
||||
String ToString(const char* format = "YYYY.MM.DD HH24:MI:SS", LanguageId lang_id = LanguageId::English) const;
|
||||
|
||||
DateTime& operator=(const DateTime& other) = default;
|
||||
DateTime& operator=(DateTime&& other) noexcept = default;
|
||||
|
||||
bool operator==(const DateTime& other) const { return m_date == other.m_date && m_time == other.m_time; }
|
||||
bool operator!=(const DateTime& other) const { return !(*this == other); }
|
||||
bool operator<(const DateTime& other) const { return m_date < other.m_date || (m_date == other.m_date && m_time < other.m_time); }
|
||||
bool operator<=(const DateTime& other) const { return !(other < *this); }
|
||||
bool operator>(const DateTime& other) const { return other < *this; }
|
||||
bool operator>=(const DateTime& other) const { return !(*this < other); }
|
||||
|
||||
private:
|
||||
Date m_date;
|
||||
Time m_time;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_DATETIME_H_ */
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_DBGASSERT_H_
|
||||
#define INCLUDE_KYTY_CORE_DBGASSERT_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include <cstdlib> // IWYU pragma: keep
|
||||
|
||||
#ifndef KYTY_FINAL
|
||||
#define ASSERT_ENABLED
|
||||
#endif
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
#ifdef __clang__
|
||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4) __attribute__((analyzer_noreturn));
|
||||
int dbg_assert_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_exit_if_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
int dbg_not_implemented_handler(char const* expr, char const* file, int line) __attribute__((analyzer_noreturn));
|
||||
#else
|
||||
int dbg_exit_handler(char const* file, int line, const char* f, ...) KYTY_FORMAT_PRINTF(3, 4);
|
||||
int dbg_assert_handler(char const* expr, char const* file, int line);
|
||||
int dbg_exit_if_handler(char const* expr, char const* file, int line);
|
||||
int dbg_not_implemented_handler(char const* expr, char const* file, int line);
|
||||
#endif
|
||||
|
||||
bool dbg_is_debugger_present();
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
#define ASSERT_HALT() \
|
||||
(Kyty::Core::dbg_is_debugger_present() ? (::fflush(nullptr), *(reinterpret_cast<volatile int*>(1)) = 0) : (std::_Exit(321), 1))
|
||||
#else
|
||||
#define ASSERT_HALT() (std::_Exit(321), 1)
|
||||
#endif
|
||||
//#define UNUSED(x) ((void)sizeof(x))
|
||||
|
||||
#ifdef ASSERT_ENABLED
|
||||
#define ASSERT(x) ((void)(!(x) && Kyty::Core::dbg_assert_handler(#x, __FILE__, __LINE__) != 0 && (ASSERT_HALT(), 1) != 0))
|
||||
#define EXIT_IF(x) ((void)((x) && Kyty::Core::dbg_exit_if_handler(#x, __FILE__, __LINE__) != 0 && (ASSERT_HALT(), 1) != 0))
|
||||
#else
|
||||
//#define ASSERT(x) ((void)sizeof(x))
|
||||
//#define EXIT_IF(x) ((void)sizeof(x))
|
||||
#define ASSERT(x) \
|
||||
do \
|
||||
{ \
|
||||
constexpr bool __emp_assert_tmp = false && (x); \
|
||||
(void)__emp_assert_tmp; \
|
||||
} while (0)
|
||||
#define EXIT_IF(x) \
|
||||
do \
|
||||
{ \
|
||||
constexpr bool __emp_assert_tmp = false && (x); \
|
||||
(void)__emp_assert_tmp; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if KYTY_COMPILER == KYTY_COMPILER_MSVC
|
||||
#define EXIT(f, ...) \
|
||||
{ \
|
||||
((void)(Kyty::Core::dbg_exit_handler(__FILE__, __LINE__, f, __VA_ARGS__) && (ASSERT_HALT(), 1))); \
|
||||
}
|
||||
#else
|
||||
#define EXIT(f, s...) \
|
||||
{ \
|
||||
((void)(Kyty::Core::dbg_exit_handler(__FILE__, __LINE__, f, ##s) && (ASSERT_HALT(), 1))); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EXIT_NOT_IMPLEMENTED(x) \
|
||||
((void)((x) && Kyty::Core::dbg_not_implemented_handler(#x, __FILE__, __LINE__) != 0 && (ASSERT_HALT(), 1) != 0))
|
||||
#define KYTY_NOT_IMPLEMENTED EXIT_NOT_IMPLEMENTED(true)
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_DBGASSERT_H_ */
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_DEBUG_H_
|
||||
#define INCLUDE_KYTY_CORE_DEBUG_H_
|
||||
|
||||
#include "Kyty/Core/ArrayWrapper.h"
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
void core_debug_init(const char* app_name);
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS && KYTY_BUILD == KYTY_BUILD_DEBUG && KYTY_COMPILER == KYTY_COMPILER_CLANG
|
||||
constexpr int DEBUG_MAX_STACK_DEPTH = 20;
|
||||
#else
|
||||
constexpr int DEBUG_MAX_STACK_DEPTH = 15;
|
||||
#endif
|
||||
|
||||
struct DebugMapPrivate;
|
||||
|
||||
namespace Debug {
|
||||
String GetCompiler();
|
||||
String GetLinker();
|
||||
String GetBitness();
|
||||
} // namespace Debug
|
||||
|
||||
class DebugMap
|
||||
{
|
||||
public:
|
||||
DebugMap();
|
||||
virtual ~DebugMap();
|
||||
|
||||
void LoadMap();
|
||||
void LoadCsv();
|
||||
|
||||
void LoadMsvcLink(const String& name, int mode);
|
||||
void LoadGnuLd(const String& name, int bitness);
|
||||
void LoadLlvmLld(const String& name, int bitness);
|
||||
void LoadCsv(const String& name);
|
||||
|
||||
void DumpMap(const String& name);
|
||||
|
||||
friend struct DebugMapPrivate;
|
||||
|
||||
KYTY_CLASS_NO_COPY(DebugMap);
|
||||
|
||||
private:
|
||||
DebugMapPrivate* m_p;
|
||||
};
|
||||
|
||||
struct DebugStack
|
||||
{
|
||||
int depth {0};
|
||||
Array<void*, DEBUG_MAX_STACK_DEPTH> stack {};
|
||||
|
||||
[[nodiscard]] uintptr_t GetAddr(int i) const { return reinterpret_cast<uintptr_t>(stack[i]); }
|
||||
|
||||
void Print(int from, bool with_name = true) const;
|
||||
void PrintAndroid(int from, bool with_name = true) const;
|
||||
|
||||
void CopyTo(DebugStack* s) const
|
||||
{
|
||||
std::memcpy(s->stack, stack, sizeof(void*) * depth);
|
||||
s->depth = depth;
|
||||
}
|
||||
|
||||
static void Trace(DebugStack* stack);
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_DEBUG_H_ */
|
||||
@@ -0,0 +1,161 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_FILE_H_
|
||||
#define INCLUDE_KYTY_CORE_FILE_H_
|
||||
|
||||
#include "Kyty/Core/ByteBuffer.h"
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DateTime.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
struct SDL_RWops;
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
#ifdef CreateDirectory
|
||||
#undef CreateDirectory
|
||||
#endif
|
||||
#ifdef DeleteFile
|
||||
#undef DeleteFile
|
||||
#endif
|
||||
#ifdef CopyFile
|
||||
#undef CopyFile
|
||||
#endif
|
||||
#ifdef MoveFile
|
||||
#undef MoveFile
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
// SUBSYSTEM_DEFINE(File);
|
||||
void core_file_init();
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
enum class Encoding
|
||||
{
|
||||
Unknown,
|
||||
Utf8,
|
||||
Utf16BE,
|
||||
Utf16LE,
|
||||
Utf32BE,
|
||||
Utf32LE
|
||||
};
|
||||
|
||||
enum class Mode
|
||||
{
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite,
|
||||
WriteRead
|
||||
};
|
||||
|
||||
struct FindInfo
|
||||
{
|
||||
String path_with_name;
|
||||
String rel_path_with_name;
|
||||
DateTime last_access_time;
|
||||
DateTime last_write_time;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
struct DirEntry
|
||||
{
|
||||
String name;
|
||||
bool is_file;
|
||||
};
|
||||
|
||||
File();
|
||||
explicit File(const String& name);
|
||||
File(const String& name, Mode mode);
|
||||
virtual ~File();
|
||||
|
||||
bool Create(const String& name);
|
||||
bool Open(const String& name, Mode mode);
|
||||
bool OpenInMem(void* buf, uint32_t buf_size);
|
||||
bool OpenInMem(ByteBuffer& buf); // NOLINT(google-runtime-references)
|
||||
bool CreateInMem();
|
||||
|
||||
void Close();
|
||||
|
||||
bool Flush();
|
||||
|
||||
[[nodiscard]] uint64_t Size() const;
|
||||
[[nodiscard]] uint64_t Remaining() const;
|
||||
|
||||
bool Seek(uint64_t offset);
|
||||
[[nodiscard]] uint64_t Tell() const;
|
||||
|
||||
bool Truncate(uint64_t size);
|
||||
|
||||
[[nodiscard]] bool IsInvalid() const;
|
||||
|
||||
[[nodiscard]] bool IsEOF() const { return Tell() >= Size(); }
|
||||
|
||||
void GetLastAccessAndWriteTimeUTC(DateTime* access, DateTime* write);
|
||||
|
||||
void Read(void* data, uint32_t size, uint32_t* bytes_read = nullptr);
|
||||
ByteBuffer Read(uint32_t size);
|
||||
void Write(const void* data, uint32_t size, uint32_t* bytes_written = nullptr);
|
||||
void Write(const ByteBuffer& buf, uint32_t* bytes_written = nullptr);
|
||||
void ReadR(void* data, uint32_t size);
|
||||
void WriteR(const void* data, uint32_t size);
|
||||
|
||||
void Write(const String& str, uint32_t* bytes_written = nullptr);
|
||||
void WriteBOM();
|
||||
String ReadLine();
|
||||
String ReadWholeString();
|
||||
[[nodiscard]] Encoding GetEncoding() const;
|
||||
void SetEncoding(Encoding e);
|
||||
void DetectEncoding();
|
||||
|
||||
void Printf(const char* format, ...) KYTY_FORMAT_PRINTF(2, 3);
|
||||
void PrintfLF(const char* format, ...) KYTY_FORMAT_PRINTF(2, 3);
|
||||
|
||||
ByteBuffer ReadWholeBuffer();
|
||||
|
||||
static uint64_t Size(const String& name);
|
||||
static String Read(const String& name, Encoding e);
|
||||
|
||||
static bool IsDirectoryExisting(const String& path);
|
||||
static bool IsFileExisting(const String& name);
|
||||
static bool IsAssetFileExisting(const String& name);
|
||||
static bool CreateDirectory(const String& path);
|
||||
static bool CreateDirectories(const String& path);
|
||||
static bool DeleteDirectory(const String& path);
|
||||
static bool DeleteDirectories(const String& path);
|
||||
static bool DeleteFile(const String& name);
|
||||
|
||||
static DateTime GetLastAccessTimeUTC(const String& name);
|
||||
static DateTime GetLastWriteTimeUTC(const String& name);
|
||||
static void GetLastAccessAndWriteTimeUTC(const String& name, DateTime* access, DateTime* write);
|
||||
static bool SetLastAccessTimeUTC(const String& name, const DateTime& dt);
|
||||
static bool SetLastWriteTimeUTC(const String& name, const DateTime& dt);
|
||||
static bool SetLastAccessAndWriteTimeUTC(const String& name, const DateTime& access, const DateTime& write);
|
||||
|
||||
static Vector<FindInfo> FindFiles(const String& path);
|
||||
static Vector<DirEntry> GetDirEntries(const String& path);
|
||||
static bool CopyFile(const String& src, const String& dst);
|
||||
static bool MoveFile(const String& src, const String& dst);
|
||||
static void RemoveReadonly(const String& name);
|
||||
static void SyncDirectories(const String& src_dir, const String& dst_dir, bool del_dst = true);
|
||||
|
||||
static void SetAssetsDir(const String& dir);
|
||||
static String GetAssetsDir();
|
||||
static void SetAssetsSubDir(const String& dir);
|
||||
static String GetAssetsSubDir();
|
||||
|
||||
SDL_RWops* CreateSdlRWops();
|
||||
|
||||
KYTY_CLASS_NO_COPY(File);
|
||||
|
||||
private:
|
||||
struct FilePrivate;
|
||||
|
||||
String m_file_name;
|
||||
FilePrivate* m_p;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_FILE_H_ */
|
||||
@@ -0,0 +1,164 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_HASH_H_
|
||||
#define INCLUDE_KYTY_CORE_HASH_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
inline uint32_t hash(const void *key, uint32_t key_len)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
|
||||
const auto *ptr = static_cast<const uint8_t*>(key);
|
||||
|
||||
while(key_len >= 4)
|
||||
{
|
||||
hash += ptr[0];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[1];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[2];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[3];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
|
||||
key_len -= 4;
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
switch(key_len)
|
||||
{
|
||||
case 3:
|
||||
hash += ptr[2];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
[[fallthrough]];
|
||||
case 2:
|
||||
hash += ptr[1];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
[[fallthrough]];
|
||||
case 1:
|
||||
hash += ptr[0];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
[[fallthrough]];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hash += (hash << 3u);
|
||||
hash ^= (hash >> 11u);
|
||||
hash += (hash << 15u);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline uint32_t hash8(uint8_t key)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
|
||||
uint8_t *ptr = &key;
|
||||
|
||||
hash += ptr[0];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
|
||||
hash += (hash << 3u);
|
||||
hash ^= (hash >> 11u);
|
||||
hash += (hash << 15u);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline uint32_t hash16(uint16_t key)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
|
||||
auto *ptr = reinterpret_cast<uint8_t *>(&key);
|
||||
|
||||
hash += ptr[0];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[1];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
|
||||
hash += (hash << 3u);
|
||||
hash ^= (hash >> 11u);
|
||||
hash += (hash << 15u);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline uint32_t hash32(uint32_t key)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
|
||||
auto *ptr = reinterpret_cast<uint8_t *>(&key);
|
||||
|
||||
hash += ptr[0];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[1];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[2];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[3];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
|
||||
hash += (hash << 3u);
|
||||
hash ^= (hash >> 11u);
|
||||
hash += (hash << 15u);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline uint32_t hash64(uint64_t key)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
|
||||
auto *ptr = reinterpret_cast<uint8_t *>(&key);
|
||||
|
||||
hash += ptr[0];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[1];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[2];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[3];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[4];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[5];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[6];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
hash += ptr[7];
|
||||
hash += (hash << 10u);
|
||||
hash ^= (hash >> 6u);
|
||||
|
||||
hash += (hash << 3u);
|
||||
hash ^= (hash >> 11u);
|
||||
hash += (hash << 15u);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_HASH_H_ */
|
||||
@@ -0,0 +1,182 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_HASHMAP_H_
|
||||
#define INCLUDE_KYTY_CORE_HASHMAP_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
class HashmapPrivate;
|
||||
|
||||
//#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
//#define HASH_CALL __stdcall
|
||||
//#else
|
||||
#define KYTY_HASH_CALL
|
||||
//#endif
|
||||
|
||||
#define KYTY_HASH_DEFINE_CALC(type) \
|
||||
template <> \
|
||||
uint32_t KYTY_HASH_CALL hash_calc<>(type const* key)
|
||||
#define KYTY_HASH_DEFINE_EQUALS(type) \
|
||||
template <> \
|
||||
bool KYTY_HASH_CALL hash_key_equals(type const* key_a, type const* key_b)
|
||||
#define KYTY_HASH_CALLBACK(name, K, V, arg) \
|
||||
static void KYTY_HASH_CALL name(K* key, V* value, void* arg) /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
template <class T>
|
||||
uint32_t KYTY_HASH_CALL hash_calc(const T* key);
|
||||
template <class T>
|
||||
bool KYTY_HASH_CALL hash_key_equals(const T* key_a, const T* key_b);
|
||||
|
||||
template <class T>
|
||||
void KYTY_HASH_CALL hash_key_copy(T* key_dst, const T* key_src)
|
||||
{
|
||||
new (key_dst) T(*key_src);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void KYTY_HASH_CALL hash_value_copy(T* value_dst, const T* value_src)
|
||||
{
|
||||
new (value_dst) T(*value_src);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void KYTY_HASH_CALL hash_key_free(T* key)
|
||||
{
|
||||
key->~T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void KYTY_HASH_CALL hash_value_free(T* value)
|
||||
{
|
||||
value->~T();
|
||||
}
|
||||
|
||||
using hash_calc_func_t = uint32_t (*)(const void*);
|
||||
using hash_key_equals_func_t = bool (*)(const void*, const void*);
|
||||
using hash_key_copy_func_t = void (*)(void*, const void*);
|
||||
using hash_value_copy_func_t = void (*)(void*, const void*);
|
||||
using hash_key_free_func_t = void (*)(void*);
|
||||
using hash_value_free_func_t = void (*)(void*);
|
||||
using hash_callback_func_t = bool (*)(const void*, const void*, void*);
|
||||
|
||||
class HashmapBase
|
||||
{
|
||||
public:
|
||||
HashmapBase(uint32_t key_size, uint32_t value_size, hash_calc_func_t hash, hash_key_equals_func_t equals, hash_key_copy_func_t key_copy,
|
||||
hash_value_copy_func_t value_copy, hash_key_free_func_t key_free, hash_value_free_func_t value_free);
|
||||
|
||||
virtual ~HashmapBase();
|
||||
|
||||
void Clear();
|
||||
|
||||
[[nodiscard]] uint32_t Size() const;
|
||||
|
||||
void Put(const void* key, const void* value);
|
||||
const void* Get(const void* key) const;
|
||||
void Remove(const void* key);
|
||||
void* OperatorSquareBrackets(const void* key, const void* default_value);
|
||||
|
||||
void Start() const;
|
||||
[[nodiscard]] bool End() const;
|
||||
void Next() const;
|
||||
[[nodiscard]] const void* Value() const;
|
||||
[[nodiscard]] const void* Key() const;
|
||||
void ForEach(hash_callback_func_t callback, void* arg) const;
|
||||
[[nodiscard]] uint32_t CollisionsCount() const;
|
||||
|
||||
KYTY_CLASS_NO_COPY(HashmapBase);
|
||||
|
||||
private:
|
||||
HashmapPrivate* m_p;
|
||||
};
|
||||
|
||||
template <class K, class V>
|
||||
class Hashmap
|
||||
{
|
||||
public:
|
||||
Hashmap()
|
||||
: m_b(sizeof(K), sizeof(V), // NOLINT(bugprone-sizeof-expression)
|
||||
reinterpret_cast<hash_calc_func_t>(hash_calc<K>), reinterpret_cast<hash_key_equals_func_t>(hash_key_equals<K>),
|
||||
reinterpret_cast<hash_key_copy_func_t>(hash_key_copy<K>), reinterpret_cast<hash_value_copy_func_t>(hash_value_copy<V>),
|
||||
reinterpret_cast<hash_key_free_func_t>(hash_key_free<K>), reinterpret_cast<hash_value_free_func_t>(hash_value_free<V>))
|
||||
{
|
||||
}
|
||||
virtual ~Hashmap() = default;
|
||||
|
||||
void Clear() { m_b.Clear(); }
|
||||
|
||||
[[nodiscard]] uint32_t Size() const { return m_b.Size(); }
|
||||
|
||||
V& operator[](const K& key)
|
||||
{
|
||||
V def;
|
||||
return *(static_cast<V*>(m_b.OperatorSquareBrackets(&key, &def)));
|
||||
}
|
||||
|
||||
V& GetOrPutDef(const K& key, const V& def) { return *(static_cast<V*>(m_b.OperatorSquareBrackets(&key, &def))); }
|
||||
|
||||
void Put(const K& key, const V& value) { m_b.Put(&key, &value); }
|
||||
|
||||
[[nodiscard]] V Get(const K& key, const V& default_value = V()) const
|
||||
{
|
||||
const V* v = static_cast<const V*>(m_b.Get(&key));
|
||||
return (v ? *v : default_value);
|
||||
}
|
||||
|
||||
[[nodiscard]] const V* Find(const K& key) const { return static_cast<const V*>(m_b.Get(&key)); }
|
||||
|
||||
[[nodiscard]] bool Contains(const K& key) const { return m_b.Get(&key); }
|
||||
|
||||
void Remove(const K& key) { m_b.Remove(&key); }
|
||||
|
||||
void Start() const { m_b.Start(); }
|
||||
|
||||
[[nodiscard]] bool End() const { return m_b.End(); }
|
||||
|
||||
void Next() const { m_b.Next(); }
|
||||
|
||||
[[nodiscard]] const V& Value() const { return *(static_cast<const V*>(m_b.Value())); }
|
||||
|
||||
[[nodiscard]] const K& Key() const { return *(static_cast<const K*>(m_b.Key())); }
|
||||
|
||||
void ForEach(bool(KYTY_HASH_CALL* callback)(const K* key, const V* value, void* context), void* arg) const
|
||||
{
|
||||
m_b.ForEach(reinterpret_cast<hash_callback_func_t>(callback), arg);
|
||||
}
|
||||
|
||||
uint32_t CollisionsCount() { return m_b.CollisionsCount(); }
|
||||
|
||||
bool operator==(const Hashmap<K, V>& other) const
|
||||
{
|
||||
if (Size() != other.Size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ok = true;
|
||||
auto callback = [&ok, &other](const K* key, const V* value) {
|
||||
if (!(other.Find(*key) && other.Get(*key) == *value))
|
||||
{
|
||||
ok = false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
ForEach([](const K* key, const V* value, void* func) { return (*static_cast<decltype(callback)*>(func))(key, value); }, &callback);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool operator!=(const Hashmap<K, V>& other) const { return !(*this == other); }
|
||||
|
||||
KYTY_CLASS_NO_COPY(Hashmap);
|
||||
|
||||
private:
|
||||
HashmapBase m_b;
|
||||
};
|
||||
|
||||
#define FOR_HASH(h) for ((h).Start(); !(h).End(); (h).Next()) /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_HASHMAP_H_ */
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_JSONREADER_H_
|
||||
#define INCLUDE_KYTY_CORE_JSONREADER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
enum JsonType
|
||||
{
|
||||
JsonBool,
|
||||
JsonNULL,
|
||||
JsonNumber,
|
||||
JsonString,
|
||||
JsonArray,
|
||||
JsonObject,
|
||||
};
|
||||
|
||||
class Json
|
||||
{
|
||||
public:
|
||||
using ListType = Vector<const Json*>;
|
||||
|
||||
virtual ~Json();
|
||||
|
||||
static void Init();
|
||||
static const Json* Create(const String& str);
|
||||
static String GetError();
|
||||
|
||||
// const Json* GetItem(const String &string) const;
|
||||
// String GetString(const String &name, const String &default_value) const;
|
||||
// double GetFloat(const String &name, double default_value) const;
|
||||
// int64_t GetInt(const String &name, int64_t default_value) const;
|
||||
const Json* GetItem(const char* string) const;
|
||||
String GetString(const char* name, const String& default_value) const;
|
||||
String GetString(const char* name) const;
|
||||
double GetFloat(const char* name, double default_value) const;
|
||||
int64_t GetInt(const char* name, int64_t default_value) const;
|
||||
bool GetBool(const char* name, bool default_value) const;
|
||||
[[nodiscard]] String GetName() const { return m_name; }
|
||||
|
||||
[[nodiscard]] JsonType GetType() const { return m_type; }
|
||||
[[nodiscard]] bool IsNull() const { return m_type == JsonNULL; }
|
||||
[[nodiscard]] bool IsNumber() const { return m_type == JsonNumber; }
|
||||
[[nodiscard]] bool IsString() const { return m_type == JsonString; }
|
||||
[[nodiscard]] bool IsObject() const { return m_type == JsonObject; }
|
||||
[[nodiscard]] bool IsArray() const { return m_type == JsonArray; }
|
||||
[[nodiscard]] bool IsBool() const { return m_type == JsonBool; }
|
||||
[[nodiscard]] String ToString() const { return m_value_string; }
|
||||
[[nodiscard]] double ToFloat() const { return m_value_double; }
|
||||
[[nodiscard]] int64_t ToInt() const { return m_value_int; }
|
||||
[[nodiscard]] int64_t ToBool() const { return static_cast<int64_t>(m_value_bool); }
|
||||
[[nodiscard]] const ListType& ToArray() const { return m_list; }
|
||||
|
||||
[[nodiscard]] StringList DbgCheckList(const StringList& required, const StringList& optional) const;
|
||||
|
||||
KYTY_CLASS_NO_COPY(Json);
|
||||
|
||||
private:
|
||||
Json() = default;
|
||||
|
||||
const char32_t* parse_value(const char32_t* value);
|
||||
const char32_t* parse_array(const char32_t* value);
|
||||
const char32_t* parse_object(const char32_t* value);
|
||||
const char32_t* parse_string(const char32_t* str);
|
||||
const char32_t* parse_number(const char32_t* value);
|
||||
|
||||
ListType m_list;
|
||||
JsonType m_type = JsonNULL;
|
||||
String m_value_string;
|
||||
int64_t m_value_int = 0;
|
||||
double m_value_double = 0.0;
|
||||
bool m_value_bool = false;
|
||||
String m_name;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_JSONREADER_H_ */
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_LANGUAGE_H_
|
||||
#define INCLUDE_KYTY_CORE_LANGUAGE_H_
|
||||
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
// SUBSYSTEM_DEFINE(Language);
|
||||
|
||||
enum class LanguageId
|
||||
{
|
||||
Unknown,
|
||||
// Arabic,
|
||||
// Chinese,
|
||||
German,
|
||||
English,
|
||||
French,
|
||||
// Hindi,
|
||||
Italian,
|
||||
// Japanese,
|
||||
// Korean,
|
||||
Portuguese,
|
||||
Russian,
|
||||
Spanish
|
||||
};
|
||||
|
||||
namespace Language {
|
||||
void Init();
|
||||
|
||||
StringList GetLanguages();
|
||||
LanguageId GetId(const String& id);
|
||||
String GetCharList(const String& id);
|
||||
String GetLettersList(const String& id);
|
||||
String GetLettersList(LanguageId lang_id);
|
||||
String GetNumericList(const String& id);
|
||||
String GetPunctuationList(const String& id);
|
||||
String GetCharListAll();
|
||||
String GetNameOfMonth(int month, LanguageId lang_id);
|
||||
String GetNameOfMonthShort(int month, LanguageId lang_id);
|
||||
String GetNameOfDay(int day, LanguageId lang_id);
|
||||
String GetNameOfDayShort(int day, LanguageId lang_id);
|
||||
} // namespace Language
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_LANGUAGE_H_ */
|
||||
@@ -0,0 +1,317 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_LINKLIST_H_
|
||||
#define INCLUDE_KYTY_CORE_LINKLIST_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/SafeDelete.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
template <typename T>
|
||||
class List;
|
||||
|
||||
// typedef struct {void *p;} ListIndex;
|
||||
using ListIndex = struct
|
||||
{
|
||||
void* p;
|
||||
};
|
||||
|
||||
#define FOR_LIST(index, list) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
|
||||
for (Core::ListIndex index = (list).First(); (list).IndexValid(index); \
|
||||
index = (list).Next(index)) /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
#define FOR_LIST_R(index, list) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
|
||||
for (Core::ListIndex index = (list).Last(); (list).IndexValid(index); \
|
||||
index = (list).Prev(index)) /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
template <typename T>
|
||||
class ListNode
|
||||
{
|
||||
/*private:*/
|
||||
|
||||
friend class List<T>;
|
||||
|
||||
explicit ListNode(const T& v): m_value(v), m_next(this), m_prev(this) {}
|
||||
|
||||
virtual ~ListNode() { Remove(); }
|
||||
|
||||
void Remove()
|
||||
{
|
||||
m_prev->m_next = m_next;
|
||||
m_next->m_prev = m_prev;
|
||||
m_next = this;
|
||||
m_prev = this;
|
||||
}
|
||||
|
||||
void InsertBefore(ListNode<T>* node)
|
||||
{
|
||||
m_next = node;
|
||||
m_prev = node->m_prev;
|
||||
node->m_prev = this;
|
||||
m_prev->m_next = this;
|
||||
}
|
||||
|
||||
[[nodiscard]] ListNode<T>* PrevNode() const { return m_prev; }
|
||||
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDelete)
|
||||
[[nodiscard]] ListNode<T>* NextNode() const { return m_next; }
|
||||
|
||||
T& Value() { return m_value; }
|
||||
|
||||
T m_value;
|
||||
ListNode<T>* m_next;
|
||||
ListNode<T>* m_prev;
|
||||
|
||||
KYTY_CLASS_NO_COPY(ListNode);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class List
|
||||
{
|
||||
/*private:*/
|
||||
template <typename T2>
|
||||
using IsNotListType = typename std::enable_if<!std::is_same<typename std::remove_reference<T2>::type, T>::value>::type;
|
||||
|
||||
public:
|
||||
using Index = ListIndex;
|
||||
|
||||
List() = default;
|
||||
|
||||
List(const List<T>& list) { (*this) = list; }
|
||||
|
||||
List(List<T>&& list) noexcept { (*this) = list; }
|
||||
|
||||
virtual ~List() { Clear(); }
|
||||
|
||||
[[nodiscard]] uint32_t Size() const { return m_size; }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (m_head)
|
||||
{
|
||||
while (m_head->NextNode() != m_head)
|
||||
{
|
||||
delete m_head->NextNode();
|
||||
}
|
||||
DeleteProtected(m_head);
|
||||
}
|
||||
m_head = nullptr;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
virtual Index Add(const T& v) { return add(v); }
|
||||
|
||||
[[nodiscard]] bool IndexValid(Index index) const { return !(index.p == nullptr); }
|
||||
|
||||
[[nodiscard]] Index First() const
|
||||
{
|
||||
Index ret = {m_head};
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] Index Last() const
|
||||
{
|
||||
Index ret = {m_head ? m_head->PrevNode() : nullptr};
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] Index Next(Index index) const
|
||||
{
|
||||
auto* node = static_cast<ListNode<T>*>(index.p);
|
||||
if (node)
|
||||
{
|
||||
node = node->NextNode();
|
||||
if (node == m_head)
|
||||
{
|
||||
node = nullptr;
|
||||
}
|
||||
}
|
||||
Index ret = {node};
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] Index Prev(Index index) const
|
||||
{
|
||||
auto* node = static_cast<ListNode<T>*>(index.p);
|
||||
if (node)
|
||||
{
|
||||
node = node->PrevNode();
|
||||
if (node->NextNode() == m_head)
|
||||
{
|
||||
node = nullptr;
|
||||
}
|
||||
}
|
||||
Index ret = {node};
|
||||
return ret;
|
||||
}
|
||||
|
||||
T& operator[](Index index)
|
||||
{
|
||||
EXIT_IF(!IndexValid(index));
|
||||
|
||||
auto* node = static_cast<ListNode<T>*>(index.p);
|
||||
|
||||
return node->Value();
|
||||
}
|
||||
|
||||
const T& operator[](Index index) const
|
||||
{
|
||||
EXIT_IF(!IndexValid(index));
|
||||
|
||||
auto* node = static_cast<ListNode<T>*>(index.p);
|
||||
|
||||
return node->Value();
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& At(Index index) const
|
||||
{
|
||||
EXIT_IF(!IndexValid(index));
|
||||
|
||||
auto* node = static_cast<ListNode<T>*>(index.p);
|
||||
|
||||
return node->Value();
|
||||
}
|
||||
|
||||
[[nodiscard]] Index Find(const T& value) const
|
||||
{
|
||||
FOR_LIST(index, (*this))
|
||||
{
|
||||
if ((*this)[index] == value)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
Index ret = {nullptr};
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T2, typename OP>
|
||||
[[nodiscard]] Index Find(const T2& t, OP&& op_eq) const
|
||||
{
|
||||
FOR_LIST(index, (*this))
|
||||
{
|
||||
if (op_eq((*this)[index], t))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
Index ret = {nullptr};
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T2, typename T3, typename OP>
|
||||
[[nodiscard]] Index Find(const T2& t2, const T3& t3, OP&& op_eq) const
|
||||
{
|
||||
FOR_LIST(index, (*this))
|
||||
{
|
||||
if (op_eq((*this)[index], t2, t3))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
Index ret = {nullptr};
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Contains(const T& value) const { return IndexValid(Find(value)); }
|
||||
|
||||
Index Remove(const T& value)
|
||||
{
|
||||
Index index = Find(value);
|
||||
return Remove(index);
|
||||
}
|
||||
|
||||
Index Remove(Index index)
|
||||
{
|
||||
if (!IndexValid(index))
|
||||
{
|
||||
Index ret = {nullptr};
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto* node = static_cast<ListNode<T>*>(index.p);
|
||||
auto* next = static_cast<ListNode<T>*>(Next(index).p);
|
||||
|
||||
if (node == m_head)
|
||||
{
|
||||
if (next == nullptr)
|
||||
{
|
||||
DeleteProtected(m_head);
|
||||
m_head = nullptr;
|
||||
m_size = 0;
|
||||
Index ret = {nullptr};
|
||||
return ret;
|
||||
}
|
||||
|
||||
m_head = next;
|
||||
}
|
||||
|
||||
DeleteProtected(node);
|
||||
m_size--;
|
||||
Index ret = {next};
|
||||
return ret;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
|
||||
List<T>& operator=(const List<T>& list)
|
||||
{
|
||||
if (this != &list)
|
||||
{
|
||||
Clear();
|
||||
FOR_LIST(index, list) { add(list[index]); }
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
List<T>& operator=(List<T>&& list) noexcept
|
||||
{
|
||||
*this = list;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Index add(const T& v)
|
||||
{
|
||||
auto* node = new ListNode<T>(v);
|
||||
|
||||
if (m_head)
|
||||
{
|
||||
node->InsertBefore(m_head);
|
||||
} else
|
||||
{
|
||||
m_head = node;
|
||||
}
|
||||
|
||||
m_size++;
|
||||
|
||||
Index ret = {node};
|
||||
return ret;
|
||||
}
|
||||
|
||||
ListNode<T>* m_head = {nullptr};
|
||||
uint32_t m_size = {0};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ListSet: public List<T>
|
||||
{
|
||||
public:
|
||||
typename List<T>::Index Add(const T& v) override
|
||||
{
|
||||
typename List<T>::Index index = this->Find(v);
|
||||
if (!this->IndexValid(index))
|
||||
{
|
||||
return List<T>::Add(v);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_LINKLIST_H_ */
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_MAGICENUM_H_
|
||||
#define INCLUDE_KYTY_CORE_MAGICENUM_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
#include "magic_enum.hpp" // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
template <typename E>
|
||||
inline String EnumName(E v)
|
||||
{
|
||||
auto str = magic_enum::enum_name(v);
|
||||
return String::FromUtf8(str.data(), static_cast<uint32_t>(str.length()));
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
inline E EnumValue(const String& str, E default_value)
|
||||
{
|
||||
auto v = magic_enum::enum_cast<E>(str.C_Str());
|
||||
if (v.has_value())
|
||||
{
|
||||
return v.value();
|
||||
}
|
||||
return default_value;
|
||||
}
|
||||
|
||||
#define KYTY_ENUM_RANGE(e, mx, mn) \
|
||||
namespace magic_enum::customize { \
|
||||
template <> \
|
||||
struct enum_range<e> \
|
||||
{ \
|
||||
static constexpr int min = (mx); \
|
||||
static constexpr int max = (mn); \
|
||||
}; \
|
||||
}
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_MAGICENUM_H_ */
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_MEMORYALLOC_H_
|
||||
#define INCLUDE_KYTY_CORE_MEMORYALLOC_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
// SUBSYSTEM_DEFINE(Memory);
|
||||
void core_memory_init();
|
||||
|
||||
struct MemStats
|
||||
{
|
||||
int state;
|
||||
size_t total_allocated;
|
||||
uint32_t blocks_num;
|
||||
};
|
||||
|
||||
void* mem_alloc(size_t size);
|
||||
void* mem_realloc(void* ptr, size_t size);
|
||||
void mem_free(void* ptr);
|
||||
void mem_print(int from_state);
|
||||
void mem_get_stat(MemStats* s);
|
||||
void mem_set_max_size(size_t size);
|
||||
int mem_new_state();
|
||||
bool mem_tracker_enabled();
|
||||
void mem_tracker_enable();
|
||||
void mem_tracker_disable();
|
||||
bool mem_check(const void* ptr);
|
||||
|
||||
#define KYTY_MEM_CHECK(ptr) EXIT_IF(!mem_check(ptr))
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_MEMORYALLOC_H_ */
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_REFCOUNTER_H_
|
||||
#define INCLUDE_KYTY_CORE_REFCOUNTER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
template <class MutexPolicy>
|
||||
class RefCounter
|
||||
{
|
||||
public:
|
||||
RefCounter() = default;
|
||||
|
||||
virtual ~RefCounter() = default;
|
||||
|
||||
void Release() const
|
||||
{
|
||||
Lock();
|
||||
if (DecRef() == 0)
|
||||
{
|
||||
Unlock();
|
||||
delete this;
|
||||
} else
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
template <class PtrType>
|
||||
void CopyPtr(PtrType** dst, PtrType* src) const
|
||||
{
|
||||
Lock();
|
||||
*dst = src;
|
||||
AddRef();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
template <class PtrType>
|
||||
void CopyOnWrite(PtrType** data) const
|
||||
{
|
||||
Lock();
|
||||
if (Refs() > 1)
|
||||
{
|
||||
if (DecRef() == 0)
|
||||
{
|
||||
Unlock();
|
||||
delete this;
|
||||
} else
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
*data = new PtrType(**data);
|
||||
} else
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
KYTY_CLASS_NO_COPY(RefCounter);
|
||||
|
||||
private:
|
||||
uint32_t AddRef() const { return ++m_refs; }
|
||||
|
||||
uint32_t Refs() const { return m_refs; }
|
||||
|
||||
uint32_t DecRef() const
|
||||
{
|
||||
EXIT_IF(m_refs == 0);
|
||||
|
||||
uint32_t ret = --m_refs;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Lock() const { m_mutex.Lock(); }
|
||||
|
||||
void Unlock() const { m_mutex.Unlock(); }
|
||||
|
||||
mutable uint32_t m_refs = {1};
|
||||
mutable MutexPolicy m_mutex;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_REFCOUNTER_H_ */
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef INCLUDE_KYTY_GAME_SDLSUBSYSTEM_H_
|
||||
#define INCLUDE_KYTY_GAME_SDLSUBSYSTEM_H_
|
||||
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(SDL);
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_GAME_SDLSUBSYSTEM_H_ */
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_SAFEDELETE_H_
|
||||
#define INCLUDE_KYTY_CORE_SAFEDELETE_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
#define KYTY_CORE_SAFE_DELETE_DEADBEEF (reinterpret_cast<void*>((uintptr_t)0x01))
|
||||
|
||||
#define DeleteProtected(p) /* NOLINT(cppcoreguidelines-macro-usage) */ \
|
||||
{ \
|
||||
if (!(p)) \
|
||||
{ \
|
||||
EXIT("delete null\n"); \
|
||||
} \
|
||||
void* dddd = KYTY_CORE_SAFE_DELETE_DEADBEEF; \
|
||||
if (std::memcmp(&(p), &dddd, sizeof(void*)) == 0) \
|
||||
{ \
|
||||
EXIT("already deleted\n"); \
|
||||
} \
|
||||
delete (p); \
|
||||
std::memcpy(&(p), &dddd, sizeof(void*)); \
|
||||
}
|
||||
|
||||
#define DeleteProtectedArray(p) /* NOLINT(cppcoreguidelines-macro-usage) */ \
|
||||
{ \
|
||||
if (!(p)) \
|
||||
{ \
|
||||
EXIT("delete null\n"); \
|
||||
} \
|
||||
void* dddd = KYTY_CORE_SAFE_DELETE_DEADBEEF; \
|
||||
if (std::memcmp(&(p), &dddd, sizeof(void*)) == 0) \
|
||||
{ \
|
||||
EXIT("already deleted\n"); \
|
||||
} \
|
||||
delete[](p); \
|
||||
std::memcpy(&(p), &dddd, sizeof(void*)); \
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Delete(T*& p)
|
||||
{
|
||||
if (!p)
|
||||
{
|
||||
EXIT("delete null\n");
|
||||
}
|
||||
if (p == static_cast<T*>(KYTY_CORE_SAFE_DELETE_DEADBEEF))
|
||||
{
|
||||
EXIT("already deleted\n");
|
||||
}
|
||||
delete p;
|
||||
p = static_cast<T*>(KYTY_CORE_SAFE_DELETE_DEADBEEF);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void DeleteArray(T*& p)
|
||||
{
|
||||
if (!p)
|
||||
{
|
||||
EXIT("delete null\n");
|
||||
}
|
||||
if (p == static_cast<T*>(KYTY_CORE_SAFE_DELETE_DEADBEEF))
|
||||
{
|
||||
EXIT("already deleted\n");
|
||||
}
|
||||
delete[] p;
|
||||
p = static_cast<T*>(KYTY_CORE_SAFE_DELETE_DEADBEEF);
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_SAFEDELETE_H_ */
|
||||
@@ -0,0 +1,647 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_SIMPLEARRAY_H_
|
||||
#define INCLUDE_KYTY_CORE_SIMPLEARRAY_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Hash.h"
|
||||
#include "Kyty/Core/MemoryAlloc.h"
|
||||
#include "Kyty/Core/RefCounter.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
#define KYTY_ARRAY_DEFINE_SWAP(name, type) \
|
||||
void name(type* array, int32_t i, int32_t j, [[maybe_unused]] void* arg) /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
template <typename T, typename R>
|
||||
using IsTriviallyCopyable = typename std::enable_if<std::is_trivially_copyable<T>::value, R>::type;
|
||||
|
||||
template <typename T, typename R>
|
||||
using IsNotTriviallyCopyable = typename std::enable_if<!std::is_trivially_copyable<T>::value, R>::type;
|
||||
|
||||
template <typename T>
|
||||
class SimpleArray: public RefCounter<Mutex>
|
||||
{
|
||||
public:
|
||||
using ValueType = T;
|
||||
using ArrayType = SimpleArray<T>;
|
||||
using SortSwapFunc = void (*)(T*, int32_t, int32_t, void*);
|
||||
using SortCompareFunc = bool (*)(const T&, const T&);
|
||||
|
||||
static constexpr size_t SIZEOF_T = sizeof(T); // NOLINT(bugprone-sizeof-expression)
|
||||
|
||||
SimpleArray() = default;
|
||||
|
||||
SimpleArray(const ArrayType& src) { copy(src); }
|
||||
|
||||
SimpleArray(ArrayType&& src) = delete;
|
||||
|
||||
explicit SimpleArray(uint32_t size, bool ctor = true)
|
||||
: m_values_num(size), m_values_limit(size), m_values(static_cast<T*>(mem_alloc(m_values_limit * SIZEOF_T)))
|
||||
{
|
||||
if (ctor)
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
new (m_values + index) T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SimpleArray(std::initializer_list<T> list): SimpleArray(static_cast<uint32_t>(list.size()))
|
||||
{
|
||||
T* values_ptr = m_values;
|
||||
for (const T& e: list)
|
||||
{
|
||||
*(values_ptr++) = e;
|
||||
}
|
||||
}
|
||||
|
||||
~SimpleArray() override { Free(); }
|
||||
|
||||
uint32_t Size() const { return m_values_num; }
|
||||
|
||||
uint32_t Capacity() const { return m_values_limit; }
|
||||
|
||||
uint32_t Hash() { return hash(); } // @suppress("Ambiguous problem")
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
m_values[index].~T();
|
||||
}
|
||||
m_values_num = 0;
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
void Free()
|
||||
{
|
||||
Clear();
|
||||
if (m_values)
|
||||
{
|
||||
mem_free(m_values);
|
||||
}
|
||||
m_values_limit = 0;
|
||||
m_values = nullptr;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
|
||||
SimpleArray<T>& operator=(const ArrayType& src)
|
||||
{
|
||||
if (this != &src)
|
||||
{
|
||||
Free();
|
||||
copy(src);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayType& operator=(ArrayType&& src) = delete;
|
||||
|
||||
bool operator==(const ArrayType& s) const
|
||||
{
|
||||
if (m_values_num != s.m_values_num)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
if (!(m_values[index] == s.m_values[index]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Expand(uint32_t num) { expand(num); } // @suppress("Ambiguous problem")
|
||||
|
||||
void Add(const T& val)
|
||||
{
|
||||
uint32_t values_i = m_values_num;
|
||||
expand(1); // @suppress("Ambiguous problem")
|
||||
m_values_num = values_i + 1;
|
||||
new (m_values + values_i) T(val);
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
void Add(T&& val)
|
||||
{
|
||||
uint32_t values_i = m_values_num;
|
||||
expand(1); // @suppress("Ambiguous problem")
|
||||
m_values_num = values_i + 1;
|
||||
new (m_values + values_i) T(std::forward<T>(val));
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
void Add(const T* val, uint32_t num)
|
||||
{
|
||||
uint32_t values_i = m_values_num;
|
||||
expand(num); // @suppress("Ambiguous problem")
|
||||
m_values_num = values_i + num;
|
||||
for (uint32_t i = 0; i < num; i++)
|
||||
{
|
||||
new (m_values + values_i + i) T(val[i]);
|
||||
}
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
void InsertAt(uint32_t index, const T& val)
|
||||
{
|
||||
Add(val);
|
||||
if (IndexValid(index))
|
||||
{
|
||||
for (uint32_t last_index = m_values_num - 1; last_index != index; last_index--)
|
||||
{
|
||||
std::swap(m_values[last_index], m_values[last_index - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InsertAt(uint32_t index, T&& val)
|
||||
{
|
||||
Add(std::forward<T>(val));
|
||||
if (IndexValid(index))
|
||||
{
|
||||
for (uint32_t last_index = m_values_num - 1; last_index != index; last_index--)
|
||||
{
|
||||
std::swap(m_values[last_index], m_values[last_index - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Find(const T& t) const
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
if (m_values[index] == t)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return uint32_t(-1);
|
||||
}
|
||||
|
||||
template <typename OP>
|
||||
uint32_t Find(const T& t, OP&& op_eq) const
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
if (op_eq(m_values[index], t))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return uint32_t(-1);
|
||||
}
|
||||
|
||||
template <typename T2, typename OP>
|
||||
uint32_t Find(const T2& t, OP&& op_eq) const
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
if (op_eq(m_values[index], t))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return uint32_t(-1);
|
||||
}
|
||||
|
||||
template <typename T2, typename OP, typename V>
|
||||
void FindAll(const T2& t, OP&& op_eq, V* ret) const
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
if (op_eq(m_values[index], t))
|
||||
{
|
||||
ret->Add(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T2, typename T3, typename OP>
|
||||
uint32_t Find(const T2& t2, const T3& t3, OP&& op_eq) const
|
||||
{
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
if (op_eq(m_values[index], t2, t3))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return uint32_t(-1);
|
||||
}
|
||||
|
||||
bool Remove(const T& t)
|
||||
{
|
||||
uint32_t index = Find(t);
|
||||
if (index == uint32_t(-1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return RemoveAt(index);
|
||||
}
|
||||
|
||||
bool RemoveAt(uint32_t index, uint32_t count = 1) { return remove_at(index, count); } // @suppress("Ambiguous problem")
|
||||
|
||||
[[nodiscard]] bool IndexValid(uint32_t index) const { return index < m_values_num; }
|
||||
|
||||
T& operator[](uint32_t index)
|
||||
{
|
||||
m_hash = 0;
|
||||
|
||||
if (index >= m_values_num)
|
||||
{
|
||||
EXIT_IF(index >= m_values_num);
|
||||
}
|
||||
|
||||
return m_values[index];
|
||||
}
|
||||
|
||||
const T& operator[](uint32_t index) const
|
||||
{
|
||||
EXIT_IF(index >= m_values_num);
|
||||
|
||||
return m_values[index];
|
||||
}
|
||||
|
||||
const T& At(uint32_t index) const
|
||||
{
|
||||
if (index >= m_values_num)
|
||||
{
|
||||
EXIT_IF(index >= m_values_num);
|
||||
}
|
||||
|
||||
return m_values[index];
|
||||
}
|
||||
|
||||
T* GetData()
|
||||
{
|
||||
m_hash = 0;
|
||||
return m_values;
|
||||
}
|
||||
|
||||
const T* GetData() const { return m_values; }
|
||||
|
||||
const T* GetDataConst() const { return m_values; }
|
||||
|
||||
void Memset(int c)
|
||||
{
|
||||
m_hash = 0;
|
||||
memset(m_values, c, m_values_num * SIZEOF_T);
|
||||
}
|
||||
|
||||
void Sort()
|
||||
{
|
||||
if (m_values_num == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sort(0, m_values_num - 1, 0);
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
void Sort(SortCompareFunc comp_func)
|
||||
{
|
||||
if (m_values_num == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sort_with_compare_func(0, m_values_num - 1, 0, comp_func);
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
void Sort(SortSwapFunc swap_func, void* swap_arg)
|
||||
{
|
||||
if (m_values_num == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sort_with_swap_func(0, m_values_num - 1, 0, swap_func, swap_arg);
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
template <typename OP>
|
||||
void Sort(OP&& comp_func)
|
||||
{
|
||||
if (m_values_num == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sort_with_compare_func(0, m_values_num - 1, 0, comp_func);
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
|
||||
iterator begin() // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
m_hash = 0;
|
||||
return m_values;
|
||||
}
|
||||
iterator end() // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
m_hash = 0;
|
||||
return m_values + m_values_num;
|
||||
}
|
||||
const_iterator begin() const { return m_values; } // NOLINT(readability-identifier-naming)
|
||||
const_iterator end() const { return m_values + m_values_num; } // NOLINT(readability-identifier-naming)
|
||||
const_iterator cbegin() const { return m_values; } // NOLINT(readability-identifier-naming)
|
||||
const_iterator cend() const { return m_values + m_values_num; } // NOLINT(readability-identifier-naming)
|
||||
|
||||
private:
|
||||
template <typename U = T>
|
||||
IsNotTriviallyCopyable<U, void> copy(const ArrayType& src)
|
||||
{
|
||||
m_values_num = src.m_values_num;
|
||||
m_values_limit = src.m_values_limit;
|
||||
m_hash = src.m_hash;
|
||||
if (src.m_values)
|
||||
{
|
||||
m_values = static_cast<T*>(mem_alloc(m_values_limit * SIZEOF_T));
|
||||
for (uint32_t index = 0; index < m_values_num; index++)
|
||||
{
|
||||
new (m_values + index) T(src.m_values[index]);
|
||||
}
|
||||
} else
|
||||
{
|
||||
m_values = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsTriviallyCopyable<U, void> copy(const ArrayType& src)
|
||||
{
|
||||
m_values_num = src.m_values_num;
|
||||
m_values_limit = src.m_values_limit;
|
||||
m_hash = src.m_hash;
|
||||
if (src.m_values)
|
||||
{
|
||||
m_values = static_cast<T*>(mem_alloc(m_values_limit * SIZEOF_T));
|
||||
std::memcpy(m_values, src.m_values, m_values_num * SIZEOF_T);
|
||||
} else
|
||||
{
|
||||
m_values = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsNotTriviallyCopyable<U, void> expand(uint32_t add_num)
|
||||
{
|
||||
uint32_t values_i = m_values_num;
|
||||
uint32_t new_values_num = values_i + add_num;
|
||||
if (new_values_num >= m_values_limit)
|
||||
{
|
||||
m_values_limit = static_cast<uint32_t>((m_values_limit * 3) / 2 + new_values_num - m_values_limit + 1);
|
||||
T* old_values = m_values;
|
||||
m_values = static_cast<T*>(mem_alloc(m_values_limit * SIZEOF_T));
|
||||
for (uint32_t index = 0; index < values_i; index++)
|
||||
{
|
||||
new (m_values + index) T(old_values[index]);
|
||||
old_values[index].~T();
|
||||
}
|
||||
mem_free(old_values);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsTriviallyCopyable<U, void> expand(uint32_t add_num)
|
||||
{
|
||||
uint32_t values_i = m_values_num;
|
||||
uint32_t new_values_num = values_i + add_num;
|
||||
if (new_values_num >= m_values_limit)
|
||||
{
|
||||
m_values_limit = static_cast<uint32_t>((m_values_limit * 3) / 2 + new_values_num - m_values_limit + 1);
|
||||
m_values = static_cast<T*>(mem_realloc(m_values, m_values_limit * SIZEOF_T));
|
||||
}
|
||||
}
|
||||
|
||||
void sort(int32_t low, int32_t high, uint32_t depth)
|
||||
{
|
||||
EXIT_IF(depth >= 64);
|
||||
EXIT_IF(low < 0 || high < 0);
|
||||
|
||||
int32_t i = low;
|
||||
int32_t j = high;
|
||||
|
||||
const T m = m_values[static_cast<uint32_t>(i + j) >> 1u];
|
||||
do
|
||||
{
|
||||
while (m_values[i] < m)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
while (m < m_values[j])
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if (i <= j)
|
||||
{
|
||||
const T tmp = m_values[i];
|
||||
m_values[i] = m_values[j];
|
||||
m_values[j] = tmp;
|
||||
i++;
|
||||
j--;
|
||||
}
|
||||
} while (i <= j);
|
||||
|
||||
if (low < j)
|
||||
{
|
||||
sort(low, j, depth + 1);
|
||||
}
|
||||
if (i < high)
|
||||
{
|
||||
sort(i, high, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OP>
|
||||
void sort_with_compare_func(int32_t low, int32_t high, uint32_t depth, OP&& comp_func)
|
||||
{
|
||||
EXIT_IF(depth >= 64);
|
||||
EXIT_IF(low < 0 || high < 0);
|
||||
|
||||
int32_t i = low;
|
||||
int32_t j = high;
|
||||
|
||||
const T m = m_values[static_cast<uint32_t>(i + j) >> 1u];
|
||||
do
|
||||
{
|
||||
while (comp_func(m_values[i], m))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
while (comp_func(m, m_values[j]))
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if (i <= j)
|
||||
{
|
||||
const T tmp = m_values[i];
|
||||
m_values[i] = m_values[j];
|
||||
m_values[j] = tmp;
|
||||
i++;
|
||||
j--;
|
||||
}
|
||||
} while (i <= j);
|
||||
|
||||
if (low < j)
|
||||
{
|
||||
sort_with_compare_func(low, j, depth + 1, comp_func);
|
||||
}
|
||||
if (i < high)
|
||||
{
|
||||
sort_with_compare_func(i, high, depth + 1, comp_func);
|
||||
}
|
||||
}
|
||||
|
||||
void sort_with_swap_func(int32_t low, int32_t high, uint32_t depth, SortSwapFunc swap_func, void* arg)
|
||||
{
|
||||
EXIT_IF(depth >= 64);
|
||||
EXIT_IF(low < 0 || high < 0);
|
||||
|
||||
int32_t i = low;
|
||||
int32_t j = high;
|
||||
|
||||
const T m = m_values[static_cast<uint32_t>(i + j) >> 1u];
|
||||
do
|
||||
{
|
||||
while (m_values[i] < m)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
while (m < m_values[j])
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if (i <= j)
|
||||
{
|
||||
swap_func(m_values, i, j, arg);
|
||||
i++;
|
||||
j--;
|
||||
}
|
||||
} while (i <= j);
|
||||
|
||||
if (low < j)
|
||||
{
|
||||
sort_with_swap_func(low, j, depth + 1, swap_func, arg);
|
||||
}
|
||||
if (i < high)
|
||||
{
|
||||
sort_with_swap_func(i, high, depth + 1, swap_func, arg);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsNotTriviallyCopyable<U, uint32_t> hash()
|
||||
{
|
||||
if (m_hash == 0)
|
||||
{
|
||||
EXIT_IF(true);
|
||||
}
|
||||
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsTriviallyCopyable<U, uint32_t> hash()
|
||||
{
|
||||
if (m_hash == 0)
|
||||
{
|
||||
m_hash = Core::hash(m_values, SIZEOF_T * m_values_num);
|
||||
}
|
||||
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsNotTriviallyCopyable<U, bool> remove_at(uint32_t index, uint32_t count = 1)
|
||||
{
|
||||
uint32_t size = m_values_num;
|
||||
if (index >= size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index + count > size)
|
||||
{
|
||||
count = size - index;
|
||||
}
|
||||
|
||||
m_values_num = size - count;
|
||||
|
||||
uint32_t mc = size - (index + count);
|
||||
for (uint32_t i = 0; i < mc; i++)
|
||||
{
|
||||
m_values[index + i] = m_values[index + i + count];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
m_values[m_values_num + i].~T();
|
||||
}
|
||||
|
||||
m_hash = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
IsTriviallyCopyable<U, bool> remove_at(uint32_t index, uint32_t count = 1)
|
||||
{
|
||||
uint32_t size = m_values_num;
|
||||
if (index >= size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index + count > size)
|
||||
{
|
||||
count = size - index;
|
||||
}
|
||||
|
||||
m_values_num = size - count;
|
||||
|
||||
std::memmove(m_values + index, (m_values + index + count), (size - (index + count)) * SIZEOF_T);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
m_values[m_values_num + i].~T();
|
||||
}
|
||||
|
||||
m_hash = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t m_values_num {0};
|
||||
uint32_t m_values_limit {0};
|
||||
T* m_values {nullptr};
|
||||
uint32_t m_hash {0};
|
||||
};
|
||||
|
||||
#define FOR(index, array) /* NOLINT(cppcoreguidelines-macro-usage)*/ \
|
||||
uint32_t array##_size_ = (array).Size(); \
|
||||
for (uint32_t index = 0; index < array##_size_; index++) /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_SIMPLEARRAY_H_ */
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_SINGLETON_H_
|
||||
#define INCLUDE_KYTY_CORE_SINGLETON_H_
|
||||
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
template <class T>
|
||||
class Singleton
|
||||
{
|
||||
public:
|
||||
static T* Instance()
|
||||
{
|
||||
if (!g_m_instance)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
g_m_instance = static_cast<T*>(std::malloc(sizeof(T)));
|
||||
new (g_m_instance) T;
|
||||
}
|
||||
|
||||
return g_m_instance;
|
||||
}
|
||||
|
||||
KYTY_CLASS_NO_COPY(Singleton);
|
||||
|
||||
protected:
|
||||
Singleton();
|
||||
~Singleton();
|
||||
|
||||
private:
|
||||
static inline T* g_m_instance = nullptr;
|
||||
};
|
||||
|
||||
// template<class T> T* Singleton<T>::instance = 0;
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_SINGLETON_H_ */
|
||||
@@ -0,0 +1,312 @@
|
||||
#ifndef CORE_KYTYSTRING_H_
|
||||
#define CORE_KYTYSTRING_H_
|
||||
|
||||
#include "Kyty/Core/ByteBuffer.h"
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/SimpleArray.h" // IWYU pragma: export
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include <cstdarg> // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
constexpr uint32_t STRING_INVALID_INDEX = static_cast<uint32_t>(-1);
|
||||
|
||||
class StringList;
|
||||
|
||||
#define C_Str utf8_str().GetData /* NOLINT(cppcoreguidelines-macro-usage) */
|
||||
#define Ru_Str cp866_str().GetData /* NOLINT(cppcoreguidelines-macro-usage) */
|
||||
#define Win_Str cp1251_str().GetData /* NOLINT(cppcoreguidelines-macro-usage) */
|
||||
|
||||
struct CharProperty
|
||||
{
|
||||
int decimal : 1;
|
||||
int alpha : 1;
|
||||
int lower : 1;
|
||||
int upper : 1;
|
||||
int space : 1;
|
||||
int hex : 1;
|
||||
int hex_data : 5;
|
||||
int case_offset : 21;
|
||||
};
|
||||
|
||||
class Char
|
||||
{
|
||||
public:
|
||||
static int ToCp866(char32_t src, uint8_t* dst);
|
||||
static int ToCp1251(char32_t src, uint8_t* dst);
|
||||
static int ToUtf8(char32_t src, uint8_t* dst);
|
||||
static int ToUtf16(char32_t src, char16_t* dst);
|
||||
static int ToUtf32(char32_t src, char32_t* dst);
|
||||
|
||||
static bool IsDecimal(char32_t ucs4);
|
||||
static bool IsAlpha(char32_t ucs4);
|
||||
static bool IsAlphaNum(char32_t ucs4);
|
||||
static bool IsLower(char32_t ucs4);
|
||||
static bool IsUpper(char32_t ucs4);
|
||||
static bool IsSpace(char32_t ucs4);
|
||||
static bool IsHex(char32_t ucs4);
|
||||
static int HexDigit(char32_t ucs4);
|
||||
static int DecimalDigit(char32_t ucs4);
|
||||
static char32_t ToLower(char32_t ucs4);
|
||||
static char32_t ToUpper(char32_t ucs4);
|
||||
|
||||
static char32_t ReadCp866(const uint8_t** str);
|
||||
static char32_t ReadCp1251(const uint8_t** str);
|
||||
static char32_t ReadUtf8(const uint8_t** str);
|
||||
static char32_t ReadUtf16(const char16_t** str);
|
||||
static char32_t ReadUtf32(const char32_t** str);
|
||||
|
||||
static bool EqualAscii(const char32_t* utf32_str, const char* ascii_str);
|
||||
static bool EqualAsciiNoCase(const char32_t* utf32_str, const char* ascii_str);
|
||||
static bool EqualAsciiN(const char32_t* utf32_str, const char* ascii_str, int n);
|
||||
static bool EqualAsciiNoCaseN(const char32_t* utf32_str, const char* ascii_str, int n);
|
||||
};
|
||||
|
||||
class String
|
||||
{
|
||||
public:
|
||||
using DataType = SimpleArray<char32_t>;
|
||||
using Utf8 = Vector<char>;
|
||||
using Cp866 = Vector<char>;
|
||||
using Cp1251 = Vector<char>;
|
||||
using Utf16 = Vector<char16_t>;
|
||||
using Utf32 = Vector<char32_t>;
|
||||
|
||||
enum class Case
|
||||
{
|
||||
Insensitive = 0,
|
||||
Sensitive = 1
|
||||
};
|
||||
enum class SplitType
|
||||
{
|
||||
WithEmptyParts,
|
||||
SplitNoEmptyParts
|
||||
};
|
||||
|
||||
String();
|
||||
String(const String& src);
|
||||
String(String&& src) noexcept;
|
||||
String(char32_t ch, uint32_t repeat = 1); // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
String(const char32_t* str); // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
explicit String(const Utf8& utf8);
|
||||
virtual ~String();
|
||||
|
||||
[[nodiscard]] uint32_t Size() const;
|
||||
[[nodiscard]] bool IsEmpty() const;
|
||||
[[nodiscard]] bool IsInvalid() const;
|
||||
|
||||
void Clear();
|
||||
|
||||
char32_t& operator[](uint32_t index);
|
||||
const char32_t& operator[](uint32_t index) const;
|
||||
[[nodiscard]] const char32_t& At(uint32_t index) const;
|
||||
char32_t* GetData();
|
||||
[[nodiscard]] const char32_t* GetData() const;
|
||||
[[nodiscard]] const char32_t* GetDataConst() const;
|
||||
|
||||
[[nodiscard]] Utf8 utf8_str() const; // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] Utf16 utf16_str() const; // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] Utf32 utf32_str() const; // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] Cp866 cp866_str() const; // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] Cp1251 cp1251_str() const; // NOLINT(readability-identifier-naming)
|
||||
|
||||
String& operator=(const String& src);
|
||||
String& operator=(String&& src) noexcept;
|
||||
String& operator=(char32_t ch);
|
||||
String& operator=(const char32_t* utf32_str);
|
||||
String& operator=(const char* utf8_str);
|
||||
String& operator=(const char16_t* utf16_str);
|
||||
String& operator+=(const String& src);
|
||||
String& operator+=(char32_t ch);
|
||||
String& operator+=(const char32_t* utf32_str);
|
||||
String& operator+=(const char* utf8_str);
|
||||
String& operator+=(const char16_t* utf16_str);
|
||||
|
||||
friend String operator+(const String& str1, const String& str2);
|
||||
friend String operator+(const char* utf8_str1, const String& str2);
|
||||
friend String operator+(const String& str1, const char* utf8_str2);
|
||||
friend String operator+(const char32_t* utf32_str1, const String& str2);
|
||||
friend String operator+(const String& str1, const char32_t* utf32_str2);
|
||||
friend String operator+(char32_t ch, const String& str2);
|
||||
friend String operator+(const String& str1, char32_t ch);
|
||||
|
||||
[[nodiscard]] bool Equal(const String& src) const;
|
||||
[[nodiscard]] bool Equal(char32_t ch) const;
|
||||
bool Equal(const char32_t* utf32_str) const;
|
||||
bool Equal(const char* utf8_str) const;
|
||||
[[nodiscard]] bool EqualNoCase(const String& src) const;
|
||||
[[nodiscard]] bool EqualNoCase(char32_t ch) const;
|
||||
bool EqualNoCase(const char32_t* utf32_str) const;
|
||||
bool EqualNoCase(const char* utf8_str) const;
|
||||
|
||||
friend bool operator==(const String& str1, const String& str2) { return str2.Equal(str1); }
|
||||
friend bool operator==(const char* utf8_str1, const String& str2) { return str2.Equal(utf8_str1); }
|
||||
friend bool operator==(const String& str1, const char* utf8_str2) { return str1.Equal(utf8_str2); }
|
||||
friend bool operator==(const char32_t* utf32_str1, const String& str2) { return str2.Equal(utf32_str1); }
|
||||
friend bool operator==(const String& str1, const char32_t* utf32_str2) { return str1.Equal(utf32_str2); }
|
||||
friend bool operator==(char32_t ch, const String& str2) { return str2.Equal(ch); }
|
||||
friend bool operator==(const String& str1, char32_t ch) { return str1.Equal(ch); }
|
||||
friend bool operator!=(const String& str1, const String& str2) { return !str2.Equal(str1); }
|
||||
friend bool operator!=(const char* utf8_str1, const String& str2) { return !str2.Equal(utf8_str1); }
|
||||
friend bool operator!=(const String& str1, const char* utf8_str2) { return !str1.Equal(utf8_str2); }
|
||||
friend bool operator!=(const char32_t* utf32_str1, const String& str2) { return !str2.Equal(utf32_str1); }
|
||||
friend bool operator!=(const String& str1, const char32_t* utf32_str2) { return !str1.Equal(utf32_str2); }
|
||||
friend bool operator!=(char32_t ch, const String& str2) { return !str2.Equal(ch); }
|
||||
friend bool operator!=(const String& str1, char32_t ch) { return !str1.Equal(ch); }
|
||||
|
||||
[[nodiscard]] String Mid(uint32_t first, uint32_t count) const;
|
||||
[[nodiscard]] String Mid(uint32_t first) const;
|
||||
[[nodiscard]] String Left(uint32_t count) const;
|
||||
[[nodiscard]] String Right(uint32_t count) const;
|
||||
|
||||
[[nodiscard]] String ToUpper() const;
|
||||
[[nodiscard]] String ToLower() const;
|
||||
|
||||
[[nodiscard]] String TrimRight() const;
|
||||
[[nodiscard]] String TrimLeft() const;
|
||||
[[nodiscard]] String Trim() const;
|
||||
[[nodiscard]] String Simplify() const;
|
||||
|
||||
[[nodiscard]] String ReplaceChar(char32_t old_char, char32_t new_char, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] String ReplaceStr(const String& old_str, const String& new_str, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] String RemoveAt(uint32_t index, uint32_t count = 1) const;
|
||||
[[nodiscard]] String RemoveChar(char32_t ch, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] String RemoveStr(const String& str, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] String RemoveLast(uint32_t num) const;
|
||||
[[nodiscard]] String RemoveFirst(uint32_t num) const;
|
||||
[[nodiscard]] String InsertAt(uint32_t index, const String& str) const;
|
||||
|
||||
[[nodiscard]] String SafeLua() const;
|
||||
[[nodiscard]] String SafeCsv() const;
|
||||
|
||||
[[nodiscard]] uint32_t FindIndex(const String& str, uint32_t from = 0, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] uint32_t FindLastIndex(const String& str, uint32_t from = STRING_INVALID_INDEX, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] uint32_t FindIndex(char32_t chr, uint32_t from = 0, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool IndexValid(uint32_t index) const;
|
||||
[[nodiscard]] uint32_t FindLastIndex(char32_t chr, uint32_t from = STRING_INVALID_INDEX, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool ContainsStr(const String& str, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool ContainsAnyStr(const StringList& list, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool ContainsAllStr(const StringList& list, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool ContainsChar(char32_t chr, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool ContainsAnyChar(const String& list, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool ContainsAllChar(const String& list, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool EndsWith(const String& str, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool StartsWith(const String& str, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool EndsWith(char32_t chr, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] bool StartsWith(char32_t chr, Case cs = Case::Sensitive) const;
|
||||
|
||||
[[nodiscard]] String DirectoryWithoutFilename() const;
|
||||
[[nodiscard]] String FilenameWithoutDirectory() const;
|
||||
[[nodiscard]] String FilenameWithoutExtension() const;
|
||||
[[nodiscard]] String ExtensionWithoutFilename() const;
|
||||
[[nodiscard]] String FixFilenameSlash() const;
|
||||
[[nodiscard]] String FixDirectorySlash() const;
|
||||
|
||||
bool Printf(const char* format, va_list args);
|
||||
|
||||
bool Printf(const char* format, ...) KYTY_FORMAT_PRINTF(2, 3);
|
||||
static String FromPrintf(const char* format, ...) KYTY_FORMAT_PRINTF(1, 2);
|
||||
|
||||
[[nodiscard]] StringList Split(const String& sep, SplitType type = SplitType::SplitNoEmptyParts, Case cs = Case::Sensitive) const;
|
||||
[[nodiscard]] StringList Split(char32_t sep, SplitType type = SplitType::SplitNoEmptyParts, Case cs = Case::Sensitive) const;
|
||||
|
||||
[[nodiscard]] uint32_t ToUint32(int base = 10) const;
|
||||
[[nodiscard]] uint64_t ToUint64(int base = 10) const;
|
||||
[[nodiscard]] int32_t ToInt32(int base = 10) const;
|
||||
[[nodiscard]] int64_t ToInt64(int base = 10) const;
|
||||
[[nodiscard]] double ToDouble() const;
|
||||
[[nodiscard]] float ToFloat() const;
|
||||
|
||||
[[nodiscard]] uint32_t Hash() const;
|
||||
|
||||
[[nodiscard]] ByteBuffer HexToBin() const;
|
||||
static String HexFromBin(const ByteBuffer& bin);
|
||||
|
||||
bool EqualAscii(const char* ascii_str) const;
|
||||
bool EqualAsciiNoCase(const char* ascii_str) const;
|
||||
|
||||
[[nodiscard]] bool IsAlpha() const;
|
||||
|
||||
static String FromCp866(const char* utf8_str) { return String(reinterpret_cast<const uint8_t*>(utf8_str), Char::ReadCp866); }
|
||||
static String FromCp1251(const char* utf8_str) { return String(reinterpret_cast<const uint8_t*>(utf8_str), Char::ReadCp1251); }
|
||||
static String FromUtf8(const char* utf8_str) { return String(reinterpret_cast<const uint8_t*>(utf8_str), Char::ReadUtf8); }
|
||||
static String FromUtf8(const char* utf8_str, uint32_t size)
|
||||
{
|
||||
return String(reinterpret_cast<const uint8_t*>(utf8_str), Char::ReadUtf8, size, true);
|
||||
}
|
||||
static String FromUtf16(const char16_t* utf16_str) { return String(utf16_str, Char::ReadUtf16); }
|
||||
static String FromUtf32(const char32_t* utf32_str) { return String(utf32_str, Char::ReadUtf32); }
|
||||
|
||||
[[nodiscard]] String SortChars() const;
|
||||
|
||||
using iterator = char32_t*;
|
||||
using const_iterator = const char32_t*;
|
||||
|
||||
iterator begin() { return GetData(); } // NOLINT(readability-identifier-naming)
|
||||
iterator end() { return GetData() + Size(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator begin() const { return GetDataConst(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator end() const { return GetDataConst() + Size(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cbegin() const { return GetDataConst(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cend() const { return GetDataConst() + Size(); } // NOLINT(readability-identifier-naming)
|
||||
|
||||
private:
|
||||
String(const char32_t* array, uint32_t size);
|
||||
// String(const uint8_t *utf8_str);
|
||||
// String(const char16_t *utf16_str);
|
||||
|
||||
template <class T, class OP>
|
||||
String(const T* str, OP&& read, uint32_t size = 0, bool with_size = false): m_data(new DataType)
|
||||
{
|
||||
if (str == nullptr)
|
||||
{
|
||||
m_data->Add(U'\0');
|
||||
} else
|
||||
{
|
||||
// const T *ptr = (const T*)str;
|
||||
const auto* ptr = str;
|
||||
for (;;)
|
||||
{
|
||||
if (with_size && ptr - str >= size)
|
||||
{
|
||||
m_data->Add(U'\0');
|
||||
break;
|
||||
}
|
||||
char32_t u = read(&ptr);
|
||||
m_data->Add(u);
|
||||
if (u == U'\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DataType* m_data;
|
||||
};
|
||||
|
||||
class StringList: public Vector<String>
|
||||
{
|
||||
public:
|
||||
using Vector<String>::Vector;
|
||||
// StringList(): Vector<String>() {};
|
||||
// StringList(std::initializer_list<String> list): Vector<String>(list) {};
|
||||
// virtual ~StringList() {};
|
||||
|
||||
[[nodiscard]] bool Contains(const String& str, String::Case cs = String::Case::Sensitive) const;
|
||||
[[nodiscard]] String Concat(const String& str) const;
|
||||
[[nodiscard]] String Concat(char32_t chr) const;
|
||||
|
||||
[[nodiscard]] bool Equal(const StringList& str) const;
|
||||
[[nodiscard]] bool EqualNoCase(const StringList& str) const;
|
||||
bool operator==(const StringList& str) const { return this->Equal(str); }
|
||||
bool operator!=(const StringList& str) const { return !(*this == str); }
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
namespace Kyty {
|
||||
using String = Core::String;
|
||||
} // namespace Kyty
|
||||
|
||||
#endif /* CORE_KYTYSTRING_H_ */
|
||||
@@ -0,0 +1,102 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_SUBSYSTEMS_H_
|
||||
#define INCLUDE_KYTY_CORE_SUBSYSTEMS_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Singleton.h"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
class Subsystem;
|
||||
class SubsystemsListPrivate;
|
||||
class SubsystemPrivate;
|
||||
|
||||
class SubsystemsList
|
||||
{
|
||||
public:
|
||||
SubsystemsList();
|
||||
virtual ~SubsystemsList();
|
||||
void SetArgs(int argc, char* argv[]);
|
||||
|
||||
// void Add(Subsystem* s, const char* name, ...);
|
||||
void Add(Subsystem* s, std::initializer_list<Subsystem*> deps);
|
||||
|
||||
bool InitAll(bool print_msg = false);
|
||||
void DestroyAll(bool print_msg = false);
|
||||
|
||||
int* GetArgc();
|
||||
char** GetArgv();
|
||||
|
||||
[[nodiscard]] const char* GetFailName() const;
|
||||
[[nodiscard]] const char* GetFailMsg() const;
|
||||
|
||||
void ShutdownAll();
|
||||
|
||||
static SubsystemsList* Instance() { return Core::Singleton<SubsystemsList>::Instance(); }
|
||||
|
||||
KYTY_CLASS_NO_COPY(SubsystemsList);
|
||||
|
||||
private:
|
||||
SubsystemsListPrivate* m_p;
|
||||
};
|
||||
|
||||
using SubsystemsListSingleton = Kyty::Core::Singleton<SubsystemsList>;
|
||||
|
||||
class Subsystem
|
||||
{
|
||||
public:
|
||||
Subsystem();
|
||||
virtual ~Subsystem();
|
||||
|
||||
virtual const char* Id() = 0;
|
||||
virtual void Init(SubsystemsList* parent) = 0;
|
||||
virtual void Destroy(SubsystemsList* parent) = 0;
|
||||
virtual void UnexpectedShutdown(SubsystemsList* parent) = 0;
|
||||
|
||||
friend class SubsystemsListPrivate;
|
||||
|
||||
KYTY_CLASS_NO_COPY(Subsystem);
|
||||
|
||||
protected:
|
||||
void Fail(const char* format, ...) KYTY_FORMAT_PRINTF(2, 3);
|
||||
|
||||
private:
|
||||
SubsystemPrivate* m_p;
|
||||
};
|
||||
|
||||
#define KYTY_SUBSYSTEM_DEFINE(s) \
|
||||
class s##Subsystem: public Core::Subsystem \
|
||||
{ \
|
||||
public: \
|
||||
static Subsystem* Instance() { return Core::Singleton<s##Subsystem>::Instance(); } \
|
||||
const char* Id() { return #s; } \
|
||||
void Init(Core::SubsystemsList* parent); \
|
||||
void Destroy(Core::SubsystemsList* parent); \
|
||||
void UnexpectedShutdown(Core::SubsystemsList* parent); \
|
||||
}; \
|
||||
typedef Core::Singleton<s##Subsystem> s##SubsystemSingleton;
|
||||
|
||||
#define KYTY_SUBSYSTEM_INIT(s) void s##Subsystem::Init([[maybe_unused]] Core::SubsystemsList* parent)
|
||||
#define KYTY_SUBSYSTEM_DESTROY(s) void s##Subsystem::Destroy([[maybe_unused]] Core::SubsystemsList* parent)
|
||||
#define KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(s) void s##Subsystem::UnexpectedShutdown([[maybe_unused]] Core::SubsystemsList* parent)
|
||||
|
||||
#define KYTY_SUBSYSTEM_ARGC parent->GetArgc()
|
||||
#define KYTY_SUBSYSTEM_ARGV parent->GetArgv()
|
||||
|
||||
#if KYTY_COMPILER == KYTY_COMPILER_MSVC
|
||||
#define KYTY_SUBSYSTEM_FAIL(f, ...) \
|
||||
this->Fail(f, __VA_ARGS__); \
|
||||
return;
|
||||
#else
|
||||
#define KYTY_SUBSYSTEM_FAIL(f, s...) \
|
||||
this->Fail(f, ##s); \
|
||||
return;
|
||||
#endif
|
||||
|
||||
//#define KYTY_SUBSYSTEM_ADD(list, s, ...) list.Add(s##SubsystemSingleton::Instance(), #s, __VA_ARGS__);
|
||||
//#define KYTY_SUBSYSTEM_ADD2(list, ...) list.Add2(s##SubsystemSingleton::Instance(), __VA_ARGS__);
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_SUBSYSTEMS_H_ */
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_THREADS_H_
|
||||
#define INCLUDE_KYTY_CORE_THREADS_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Threads);
|
||||
|
||||
using thread_func_t = void (*)(void*);
|
||||
|
||||
// struct ThreadPrivate;
|
||||
class String;
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread(thread_func_t func, void* arg);
|
||||
virtual ~Thread();
|
||||
|
||||
void Join();
|
||||
void Detach();
|
||||
|
||||
// Once a thread has finished, the id may be reused by another thread.
|
||||
[[nodiscard]] String GetId() const;
|
||||
|
||||
static void Sleep(uint32_t millis);
|
||||
static void SleepMicro(uint32_t micros);
|
||||
static void SleepNano(uint64_t nanos);
|
||||
static bool IsMainThread();
|
||||
|
||||
// Get current thread id
|
||||
// Once a thread has finished, the id may be reused by another thread.
|
||||
static String GetThreadId();
|
||||
|
||||
// Get current thread id
|
||||
// The id is unique and can't be reused by another thread.
|
||||
static int GetThreadIdUnique();
|
||||
|
||||
KYTY_CLASS_NO_COPY(Thread);
|
||||
|
||||
private:
|
||||
struct ThreadPrivate;
|
||||
ThreadPrivate* m_thread;
|
||||
};
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
virtual ~Mutex();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool TryLock();
|
||||
|
||||
friend class CondVar;
|
||||
|
||||
KYTY_CLASS_NO_COPY(Mutex);
|
||||
|
||||
private:
|
||||
struct MutexPrivate;
|
||||
MutexPrivate* m_mutex;
|
||||
};
|
||||
|
||||
class DummyMutex final
|
||||
{
|
||||
public:
|
||||
DummyMutex() = default;
|
||||
~DummyMutex() = default;
|
||||
|
||||
void Lock() {}
|
||||
void Unlock() {}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
|
||||
bool TryLock() { return false; }
|
||||
|
||||
friend class CondVar;
|
||||
|
||||
KYTY_CLASS_NO_COPY(DummyMutex);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class CondVar
|
||||
{
|
||||
public:
|
||||
CondVar();
|
||||
virtual ~CondVar();
|
||||
|
||||
void Wait(Mutex* mutex);
|
||||
void WaitFor(Mutex* mutex, uint32_t micros);
|
||||
void Signal();
|
||||
void SignalAll();
|
||||
|
||||
KYTY_CLASS_NO_COPY(CondVar);
|
||||
|
||||
private:
|
||||
struct CondVarPrivate;
|
||||
CondVarPrivate* m_cond_var;
|
||||
};
|
||||
|
||||
class LockGuard
|
||||
{
|
||||
public:
|
||||
using mutex_type = Mutex;
|
||||
|
||||
explicit LockGuard(mutex_type& m): m_mutex(m) { m_mutex.Lock(); }
|
||||
|
||||
~LockGuard() { m_mutex.Unlock(); }
|
||||
|
||||
KYTY_CLASS_NO_COPY(LockGuard);
|
||||
|
||||
private:
|
||||
mutex_type& m_mutex;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_THREADS_H_ */
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_TIMER_H_
|
||||
#define INCLUDE_KYTY_CORE_TIMER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
class Timer final
|
||||
{
|
||||
public:
|
||||
Timer() noexcept;
|
||||
~Timer() = default;
|
||||
|
||||
void Start();
|
||||
|
||||
void Pause();
|
||||
|
||||
void Resume();
|
||||
|
||||
[[nodiscard]] bool IsPaused() const;
|
||||
|
||||
// return time in milliseconds
|
||||
[[nodiscard]] double GetTimeMs() const;
|
||||
|
||||
// return time in seconds
|
||||
[[nodiscard]] double GetTimeS() const;
|
||||
|
||||
// return time in ticks
|
||||
[[nodiscard]] uint64_t GetTicks() const;
|
||||
|
||||
// return ticks frequency
|
||||
[[nodiscard]] uint64_t GetFrequency() const;
|
||||
|
||||
KYTY_CLASS_NO_COPY(Timer);
|
||||
|
||||
[[nodiscard]] static uint64_t QueryPerformanceFrequency();
|
||||
[[nodiscard]] static uint64_t QueryPerformanceCounter();
|
||||
|
||||
private:
|
||||
bool m_is_paused = true;
|
||||
uint64_t m_Frequency = 0;
|
||||
uint64_t m_StartTime = 0;
|
||||
uint64_t m_PauseTime = 0;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_TIMER_H_ */
|
||||
@@ -0,0 +1,279 @@
|
||||
#ifndef INCLUDE_KYTY_CORE_VECTOR_H_
|
||||
#define INCLUDE_KYTY_CORE_VECTOR_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/SimpleArray.h" // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Core {
|
||||
|
||||
template <typename T>
|
||||
class SimpleArray;
|
||||
|
||||
template <typename T, class A>
|
||||
class VectorBase
|
||||
{
|
||||
public:
|
||||
using DataType = A;
|
||||
using VectorType = VectorBase<T, A>;
|
||||
using SortSwapFunc = typename A::SortSwapFunc;
|
||||
using SortCompareFunc = typename A::SortCompareFunc;
|
||||
|
||||
VectorBase(): m_data(new DataType) {}
|
||||
|
||||
VectorBase(const VectorType& src) { src.m_data->CopyPtr(&m_data, src.m_data); }
|
||||
|
||||
VectorBase(VectorType&& src) noexcept: m_data(src.m_data) { src.m_data = nullptr; }
|
||||
|
||||
explicit VectorBase(uint32_t size, bool ctor = true): m_data(size != 0u ? new DataType(size, ctor) : new DataType) {}
|
||||
|
||||
VectorBase(std::initializer_list<T> list): m_data(new DataType(list)) {}
|
||||
|
||||
virtual ~VectorBase()
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
m_data->Release();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32_t Size() const { return m_data->Size(); }
|
||||
|
||||
[[nodiscard]] uint32_t Capacity() const { return m_data->Capacity(); }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Clear();
|
||||
}
|
||||
|
||||
void Free()
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Free();
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
|
||||
VectorBase<T, A>& operator=(const VectorType& src)
|
||||
{
|
||||
if (m_data != src.m_data)
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
m_data->Release();
|
||||
}
|
||||
|
||||
src.m_data->CopyPtr(&m_data, src.m_data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorBase<T, A>& operator=(VectorType&& src) noexcept
|
||||
{
|
||||
if (m_data != src.m_data)
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
m_data->Release();
|
||||
}
|
||||
|
||||
m_data = src.m_data;
|
||||
src.m_data = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const VectorType& s) const { return *m_data == *s.m_data; }
|
||||
|
||||
bool operator!=(const VectorType& s) const { return !(*m_data == *s.m_data); }
|
||||
|
||||
void Expand(uint32_t num)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Expand(num);
|
||||
}
|
||||
|
||||
void Add(const T& val)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Add(val);
|
||||
}
|
||||
|
||||
void Add(T&& val)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Add(std::forward<T>(val));
|
||||
}
|
||||
|
||||
void Add(const T* val, uint32_t num)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Add(val, num);
|
||||
}
|
||||
|
||||
void Add(const VectorType& v)
|
||||
{
|
||||
if (this == &v)
|
||||
{
|
||||
VectorType v2(v);
|
||||
copy_on_write();
|
||||
m_data->Add(v2.GetData(), v2.Size());
|
||||
} else
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Add(v.GetData(), v.Size());
|
||||
}
|
||||
}
|
||||
|
||||
void InsertAt(uint32_t index, const T& val)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->InsertAt(index, val);
|
||||
}
|
||||
|
||||
void InsertAt(uint32_t index, T&& val)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->InsertAt(index, std::forward<T>(val));
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32_t Find(const T& t) const { return m_data->Find(t); }
|
||||
|
||||
template <typename OP>
|
||||
uint32_t Find(const T& t, OP&& op_eq) const
|
||||
{
|
||||
return m_data->Find(t, op_eq);
|
||||
}
|
||||
|
||||
template <typename T2, typename OP>
|
||||
uint32_t Find(const T2& t, OP&& op_eq) const
|
||||
{
|
||||
return m_data->Find(t, op_eq);
|
||||
}
|
||||
|
||||
template <typename T2, typename OP, typename V>
|
||||
void FindAll(const T2& t, OP&& op_eq, V* out) const
|
||||
{
|
||||
m_data->FindAll(t, op_eq, out);
|
||||
}
|
||||
|
||||
template <typename T2, typename T3, typename OP>
|
||||
uint32_t Find(const T2& t2, const T3& t3, OP&& op_eq) const
|
||||
{
|
||||
return m_data->Find(t2, t3, op_eq);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Contains(const T& t) const { return Find(t) != uint32_t(-1); }
|
||||
|
||||
template <typename T2, typename OP>
|
||||
bool Contains(const T2& t, OP&& op_eq) const
|
||||
{
|
||||
return Find(t, op_eq) != uint32_t(-1);
|
||||
}
|
||||
|
||||
bool Remove(const T& t)
|
||||
{
|
||||
copy_on_write();
|
||||
return m_data->Remove(t);
|
||||
}
|
||||
|
||||
bool RemoveAt(uint32_t index, uint32_t count = 1)
|
||||
{
|
||||
copy_on_write();
|
||||
return m_data->RemoveAt(index, count);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IndexValid(uint32_t index) const { return m_data->IndexValid(index); }
|
||||
|
||||
T& operator[](uint32_t index)
|
||||
{
|
||||
copy_on_write();
|
||||
return m_data->operator[](index);
|
||||
}
|
||||
|
||||
const T& operator[](uint32_t index) const { return m_data->At(index); }
|
||||
|
||||
[[nodiscard]] const T& At(uint32_t index) const { return m_data->At(index); }
|
||||
|
||||
T* GetData()
|
||||
{
|
||||
copy_on_write();
|
||||
return m_data->GetData();
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* GetData() const { return m_data->GetDataConst(); }
|
||||
|
||||
[[nodiscard]] const T* GetDataConst() const { return m_data->GetDataConst(); }
|
||||
|
||||
void Memset(int c)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Memset(c);
|
||||
}
|
||||
|
||||
void Sort()
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Sort();
|
||||
}
|
||||
|
||||
void Sort(SortCompareFunc comp_func)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Sort(comp_func);
|
||||
}
|
||||
|
||||
void Sort(SortSwapFunc swap_func, void* swap_arg = nullptr)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Sort(swap_func, swap_arg);
|
||||
}
|
||||
|
||||
template <typename OP>
|
||||
void Sort(OP&& comp_func)
|
||||
{
|
||||
copy_on_write();
|
||||
m_data->Sort(comp_func);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsEmpty() const { return Size() == 0; }
|
||||
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
|
||||
iterator begin() // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
copy_on_write();
|
||||
return m_data->begin();
|
||||
}
|
||||
|
||||
iterator end() // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
copy_on_write();
|
||||
return m_data->end();
|
||||
}
|
||||
|
||||
[[nodiscard]] const_iterator begin() const { return m_data->cbegin(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator end() const { return m_data->cend(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cbegin() const { return m_data->cbegin(); } // NOLINT(readability-identifier-naming)
|
||||
[[nodiscard]] const_iterator cend() const { return m_data->cend(); } // NOLINT(readability-identifier-naming)
|
||||
|
||||
private:
|
||||
void copy_on_write() { m_data->CopyOnWrite(&m_data); }
|
||||
|
||||
DataType* m_data;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Core
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
template <typename T>
|
||||
class Vector: public Core::VectorBase<T, Core::SimpleArray<T>>
|
||||
{
|
||||
public:
|
||||
using Core::VectorBase<T, Core::SimpleArray<T>>::VectorBase;
|
||||
};
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif /* INCLUDE_KYTY_CORE_VECTOR_H_ */
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_CRYPTO_H_
|
||||
#define INCLUDE_KYTY_MATH_CRYPTO_H_
|
||||
|
||||
#include "Kyty/Core/ByteBuffer.h"
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
namespace Kyty::Math {
|
||||
|
||||
namespace AES {
|
||||
enum class Mode
|
||||
{
|
||||
Cbc256Pkcs7Padding,
|
||||
Cbc256ZeroPadding
|
||||
};
|
||||
|
||||
Core::ByteBuffer Encrypt(const uint8_t* buf, uint32_t length, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
Core::ByteBuffer Encrypt(const Core::ByteBuffer& buf, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
Core::ByteBuffer EncryptStr(const String& str, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
|
||||
Core::ByteBuffer Decrypt(const uint8_t* buf, uint32_t length, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
Core::ByteBuffer Decrypt(const Core::ByteBuffer& buf, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
String DecryptStr(const uint8_t* buf, uint32_t length, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
String DecryptStr(const Core::ByteBuffer& buf, const uint8_t* key, const uint8_t* iv, Mode mode);
|
||||
|
||||
} // namespace AES
|
||||
|
||||
namespace MD5 {
|
||||
/* MD5 context. */
|
||||
struct CTX
|
||||
{
|
||||
uint32_t state[4]; /* state (ABCD) */
|
||||
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
};
|
||||
|
||||
void Init(CTX* context);
|
||||
void Update(CTX* context, const uint8_t* input, uint32_t input_len);
|
||||
void Final(uint8_t digest[16], CTX* context);
|
||||
|
||||
Core::ByteBuffer Hash(const uint8_t* buf, uint32_t length);
|
||||
Core::ByteBuffer Hash(const Core::ByteBuffer& buf);
|
||||
Core::ByteBuffer Hash(const String& str);
|
||||
} // namespace MD5
|
||||
|
||||
namespace CRC32 {
|
||||
uint32_t Hash(const uint8_t* buf, uint32_t length);
|
||||
uint32_t Hash(const Core::ByteBuffer& buf);
|
||||
uint32_t Hash(const String& str);
|
||||
} // namespace CRC32
|
||||
|
||||
} // namespace Kyty::Math
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_CRYPTO_H_ */
|
||||
@@ -0,0 +1,240 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_MAT2IMPL_H_
|
||||
#define INCLUDE_KYTY_MATH_MAT2IMPL_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
// MAT2_DECL mat2::mat2() = default;
|
||||
//
|
||||
// MAT2_DECL mat2::mat2(const mat2 &m)
|
||||
//{
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y;
|
||||
//}
|
||||
//
|
||||
// MAT2_DECL mat2::mat2(mat2 &&m) noexcept
|
||||
//{
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y;
|
||||
//}
|
||||
|
||||
MAT2_DECL mat2::mat2(const mat3& m) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = m.data[0].x;
|
||||
data[0].y = m.data[0].y;
|
||||
data[1].x = m.data[1].x;
|
||||
data[1].y = m.data[1].y;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2::mat2(const mat4& m) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = m.data[0].x;
|
||||
data[0].y = m.data[0].y;
|
||||
data[1].x = m.data[1].x;
|
||||
data[1].y = m.data[1].y;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2::mat2(float x) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = x;
|
||||
data[0].y = 0;
|
||||
data[1].x = 0;
|
||||
data[1].y = x;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2::mat2(float x1, float y1, // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
float x2, float y2) noexcept
|
||||
{
|
||||
data[0].x = x1;
|
||||
data[0].y = y1;
|
||||
data[1].x = x2;
|
||||
data[1].y = y2;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2::mat2(const vec2& v1, const vec2& v2) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = v1.x;
|
||||
data[0].y = v1.y;
|
||||
data[1].x = v2.x;
|
||||
data[1].y = v2.y;
|
||||
}
|
||||
|
||||
MAT2_DECL vec2& mat2::operator[](int i)
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 2));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
MAT2_DECL const vec2& mat2::operator[](int i) const
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 2));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
// MAT2_DECL mat2 &mat2::operator = (const mat2 &m)
|
||||
//{
|
||||
// if (this != &m)
|
||||
// {
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y;
|
||||
// }
|
||||
// return *this;
|
||||
//}
|
||||
//
|
||||
// MAT2_DECL mat2 &mat2::operator = (mat2 &&m) noexcept
|
||||
//{
|
||||
// *this = m;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator+=(float s)
|
||||
{
|
||||
data[0].x += s;
|
||||
data[0].y += s;
|
||||
data[1].x += s;
|
||||
data[1].y += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator+=(const mat2& m)
|
||||
{
|
||||
data[0].x += m.data[0].x;
|
||||
data[0].y += m.data[0].y;
|
||||
data[1].x += m.data[1].x;
|
||||
data[1].y += m.data[1].y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator-=(float s)
|
||||
{
|
||||
data[0].x -= s;
|
||||
data[0].y -= s;
|
||||
data[1].x -= s;
|
||||
data[1].y -= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator-=(const mat2& m)
|
||||
{
|
||||
data[0].x -= m.data[0].x;
|
||||
data[0].y -= m.data[0].y;
|
||||
data[1].x -= m.data[1].x;
|
||||
data[1].y -= m.data[1].y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator*=(float s)
|
||||
{
|
||||
data[0].x *= s;
|
||||
data[0].y *= s;
|
||||
data[1].x *= s;
|
||||
data[1].y *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator*=(const mat2& m)
|
||||
{
|
||||
*this = *this * m;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2& mat2::operator/=(float s)
|
||||
{
|
||||
data[0].x /= s;
|
||||
data[0].y /= s;
|
||||
data[1].x /= s;
|
||||
data[1].y /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator+(const mat2& m, float s)
|
||||
{
|
||||
return mat2(m.data[0].x + s, m.data[0].y + s, m.data[1].x + s, m.data[1].y + s);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator+(float s, const mat2& m)
|
||||
{
|
||||
return mat2(m.data[0].x + s, m.data[0].y + s, m.data[1].x + s, m.data[1].y + s);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator+(const mat2& m1, const mat2& m2)
|
||||
{
|
||||
return mat2(m1.data[0].x + m2.data[0].x, m1.data[0].y + m2.data[0].y, m1.data[1].x + m2.data[1].x, m1.data[1].y + m2.data[1].y);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator-(const mat2& m, float s)
|
||||
{
|
||||
return mat2(m.data[0].x - s, m.data[0].y - s, m.data[1].x - s, m.data[1].y - s);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator-(float s, const mat2& m)
|
||||
{
|
||||
return mat2(s - m.data[0].x, s - m.data[0].y, s - m.data[1].x, s - m.data[1].y);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator-(const mat2& m1, const mat2& m2)
|
||||
{
|
||||
return mat2(m1.data[0].x - m2.data[0].x, m1.data[0].y - m2.data[0].y, m1.data[1].x - m2.data[1].x, m1.data[1].y - m2.data[1].y);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator*(const mat2& m, float s)
|
||||
{
|
||||
return mat2(m.data[0].x * s, m.data[0].y * s, m.data[1].x * s, m.data[1].y * s);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator*(float s, const mat2& m)
|
||||
{
|
||||
return mat2(m.data[0].x * s, m.data[0].y * s, m.data[1].x * s, m.data[1].y * s);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator*(const mat2& m1, const mat2& m2)
|
||||
{
|
||||
/*#define MUL2(i, j) */ auto mul = [&m1, &m2](auto i, auto j) {
|
||||
return (m1.data[0].data[(j)] * m2.data[(i)].data[0] + m1.data[1].data[(j)] * m2.data[(i)].data[1]);
|
||||
};
|
||||
|
||||
return mat2(mul(0, 0), mul(0, 1), mul(1, 0), mul(1, 1));
|
||||
|
||||
//#undef MUL2
|
||||
}
|
||||
|
||||
MAT2_DECL vec2 operator*(const mat2& m, const vec2& v)
|
||||
{
|
||||
return vec2(m.data[0].x * v.x + m.data[1].x * v.y, m.data[0].y * v.x + m.data[1].y * v.y);
|
||||
}
|
||||
|
||||
MAT2_DECL vec2 operator*(const vec2& v, const mat2& m)
|
||||
{
|
||||
return vec2(m.data[0].x * v.x + m.data[0].y * v.y, m.data[1].x * v.x + m.data[1].y * v.y);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator/(const mat2& m, float s)
|
||||
{
|
||||
return mat2(m.data[0].x / s, m.data[0].y / s, m.data[1].x / s, m.data[1].y / s);
|
||||
}
|
||||
|
||||
MAT2_DECL mat2 operator/(float s, const mat2& m)
|
||||
{
|
||||
return mat2(s / m.data[0].x, s / m.data[0].y, s / m.data[1].x, s / m.data[1].y);
|
||||
}
|
||||
|
||||
MAT2_DECL bool operator==(const mat2& m1, const mat2& m2)
|
||||
{
|
||||
return (m1.data[0].x == m2.data[0].x) && (m1.data[0].y == m2.data[0].y) && (m1.data[1].x == m2.data[1].x) &&
|
||||
(m1.data[1].y == m2.data[1].y);
|
||||
}
|
||||
|
||||
MAT2_DECL bool operator!=(const mat2& m1, const mat2& m2)
|
||||
{
|
||||
return (m1.data[0].x != m2.data[0].x) || (m1.data[0].y != m2.data[0].y) || (m1.data[1].x != m2.data[1].x) ||
|
||||
(m1.data[1].y != m2.data[1].y);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_MAT2IMPL_H_ */
|
||||
@@ -0,0 +1,303 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_MAT3IMPL_H_
|
||||
#define INCLUDE_KYTY_MATH_MAT3IMPL_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
// MAT3_DECL mat3::mat3() = default;
|
||||
//
|
||||
// MAT3_DECL mat3::mat3(const mat3 &m)
|
||||
//{
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y; data[0].z = m.data[0].z;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y; data[1].z = m.data[1].z;
|
||||
// data[2].x = m.data[2].x; data[2].y = m.data[2].y; data[2].z = m.data[2].z;
|
||||
//}
|
||||
//
|
||||
// MAT3_DECL mat3::mat3(mat3 &&m) noexcept
|
||||
//{
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y; data[0].z = m.data[0].z;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y; data[1].z = m.data[1].z;
|
||||
// data[2].x = m.data[2].x; data[2].y = m.data[2].y; data[2].z = m.data[2].z;
|
||||
//}
|
||||
|
||||
MAT3_DECL mat3::mat3(const mat4& m) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = m.data[0].x;
|
||||
data[0].y = m.data[0].y;
|
||||
data[0].z = m.data[0].z;
|
||||
data[1].x = m.data[1].x;
|
||||
data[1].y = m.data[1].y;
|
||||
data[1].z = m.data[1].z;
|
||||
data[2].x = m.data[2].x;
|
||||
data[2].y = m.data[2].y;
|
||||
data[2].z = m.data[2].z;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3::mat3(float x) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = x;
|
||||
data[0].y = 0;
|
||||
data[0].z = 0;
|
||||
data[1].x = 0;
|
||||
data[1].y = x;
|
||||
data[1].z = 0;
|
||||
data[2].x = 0;
|
||||
data[2].y = 0;
|
||||
data[2].z = x;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3::mat3(float x1, float y1, float z1, // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
float x2, float y2, float z2, float x3, float y3, float z3) noexcept
|
||||
{
|
||||
data[0].x = x1;
|
||||
data[0].y = y1;
|
||||
data[0].z = z1;
|
||||
data[1].x = x2;
|
||||
data[1].y = y2;
|
||||
data[1].z = z2;
|
||||
data[2].x = x3;
|
||||
data[2].y = y3;
|
||||
data[2].z = z3;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
MAT3_DECL mat3::mat3(const vec3& v1, const vec3& v2, const vec3& v3) noexcept
|
||||
{
|
||||
data[0].x = v1.x;
|
||||
data[0].y = v1.y;
|
||||
data[0].z = v1.z;
|
||||
data[1].x = v2.x;
|
||||
data[1].y = v2.y;
|
||||
data[1].z = v2.z;
|
||||
data[2].x = v3.x;
|
||||
data[2].y = v3.y;
|
||||
data[2].z = v3.z;
|
||||
}
|
||||
|
||||
MAT3_DECL vec3& mat3::operator[](int i)
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 3));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
MAT3_DECL const vec3& mat3::operator[](int i) const
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 3));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
// MAT3_DECL mat3 &mat3::operator = (const mat3 &m)
|
||||
//{
|
||||
// if (this != &m)
|
||||
// {
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y; data[0].z = m.data[0].z;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y; data[1].z = m.data[1].z;
|
||||
// data[2].x = m.data[2].x; data[2].y = m.data[2].y; data[2].z = m.data[2].z;
|
||||
// }
|
||||
// return *this;
|
||||
//}
|
||||
//
|
||||
// MAT3_DECL mat3 &mat3::operator = (mat3 &&m) noexcept
|
||||
//{
|
||||
// *this = m;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator+=(float s)
|
||||
{
|
||||
data[0].x += s;
|
||||
data[0].y += s;
|
||||
data[0].z += s;
|
||||
data[1].x += s;
|
||||
data[1].y += s;
|
||||
data[1].z += s;
|
||||
data[2].x += s;
|
||||
data[2].y += s;
|
||||
data[2].z += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator+=(const mat3& m)
|
||||
{
|
||||
data[0].x += m.data[0].x;
|
||||
data[0].y += m.data[0].y;
|
||||
data[0].z += m.data[0].z;
|
||||
data[1].x += m.data[1].x;
|
||||
data[1].y += m.data[1].y;
|
||||
data[1].z += m.data[1].z;
|
||||
data[2].x += m.data[2].x;
|
||||
data[2].y += m.data[2].y;
|
||||
data[2].z += m.data[2].z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator-=(float s)
|
||||
{
|
||||
data[0].x -= s;
|
||||
data[0].y -= s;
|
||||
data[0].z -= s;
|
||||
data[1].x -= s;
|
||||
data[1].y -= s;
|
||||
data[1].z -= s;
|
||||
data[2].x -= s;
|
||||
data[2].y -= s;
|
||||
data[2].z -= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator-=(const mat3& m)
|
||||
{
|
||||
data[0].x -= m.data[0].x;
|
||||
data[0].y -= m.data[0].y;
|
||||
data[0].z -= m.data[0].z;
|
||||
data[1].x -= m.data[1].x;
|
||||
data[1].y -= m.data[1].y;
|
||||
data[1].z -= m.data[1].z;
|
||||
data[2].x -= m.data[2].x;
|
||||
data[2].y -= m.data[2].y;
|
||||
data[2].z -= m.data[2].z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator*=(float s)
|
||||
{
|
||||
data[0].x *= s;
|
||||
data[0].y *= s;
|
||||
data[0].z *= s;
|
||||
data[1].x *= s;
|
||||
data[1].y *= s;
|
||||
data[1].z *= s;
|
||||
data[2].x *= s;
|
||||
data[2].y *= s;
|
||||
data[2].z *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator*=(const mat3& m)
|
||||
{
|
||||
*this = *this * m;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3& mat3::operator/=(float s)
|
||||
{
|
||||
data[0].x /= s;
|
||||
data[0].y /= s;
|
||||
data[0].z /= s;
|
||||
data[1].x /= s;
|
||||
data[1].y /= s;
|
||||
data[1].z /= s;
|
||||
data[2].x /= s;
|
||||
data[2].y /= s;
|
||||
data[2].z /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator+(const mat3& m, float s)
|
||||
{
|
||||
return mat3(m.data[0].x + s, m.data[0].y + s, m.data[0].z + s, m.data[1].x + s, m.data[1].y + s, m.data[1].z + s, m.data[2].x + s,
|
||||
m.data[2].y + s, m.data[2].z + s);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator+(float s, const mat3& m)
|
||||
{
|
||||
return mat3(m.data[0].x + s, m.data[0].y + s, m.data[0].z + s, m.data[1].x + s, m.data[1].y + s, m.data[1].z + s, m.data[2].x + s,
|
||||
m.data[2].y + s, m.data[2].z + s);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator+(const mat3& m1, const mat3& m2)
|
||||
{
|
||||
return mat3(m1.data[0].x + m2.data[0].x, m1.data[0].y + m2.data[0].y, m1.data[0].z + m2.data[0].z, m1.data[1].x + m2.data[1].x,
|
||||
m1.data[1].y + m2.data[1].y, m1.data[1].z + m2.data[1].z, m1.data[2].x + m2.data[2].x, m1.data[2].y + m2.data[2].y,
|
||||
m1.data[2].z + m2.data[2].z);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator-(const mat3& m, float s)
|
||||
{
|
||||
return mat3(m.data[0].x - s, m.data[0].y - s, m.data[0].z - s, m.data[1].x - s, m.data[1].y - s, m.data[1].z - s, m.data[2].x - s,
|
||||
m.data[2].y - s, m.data[2].z - s);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator-(float s, const mat3& m)
|
||||
{
|
||||
return mat3(s - m.data[0].x, s - m.data[0].y, s - m.data[0].z, s - m.data[1].x, s - m.data[1].y, s - m.data[1].z, s - m.data[2].x,
|
||||
s - m.data[2].y, s - m.data[2].z);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator-(const mat3& m1, const mat3& m2)
|
||||
{
|
||||
return mat3(m1.data[0].x - m2.data[0].x, m1.data[0].y - m2.data[0].y, m1.data[0].z - m2.data[0].z, m1.data[1].x - m2.data[1].x,
|
||||
m1.data[1].y - m2.data[1].y, m1.data[1].z - m2.data[1].z, m1.data[2].x - m2.data[2].x, m1.data[2].y - m2.data[2].y,
|
||||
m1.data[2].z - m2.data[2].z);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator*(const mat3& m, float s)
|
||||
{
|
||||
return mat3(m.data[0].x * s, m.data[0].y * s, m.data[0].z * s, m.data[1].x * s, m.data[1].y * s, m.data[1].z * s, m.data[2].x * s,
|
||||
m.data[2].y * s, m.data[2].z * s);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator*(float s, const mat3& m)
|
||||
{
|
||||
return mat3(m.data[0].x * s, m.data[0].y * s, m.data[0].z * s, m.data[1].x * s, m.data[1].y * s, m.data[1].z * s, m.data[2].x * s,
|
||||
m.data[2].y * s, m.data[2].z * s);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator*(const mat3& m1, const mat3& m2)
|
||||
{
|
||||
/*#define MUL3(i, j) */ auto mul3 = [&](auto i, auto j) {
|
||||
return (m1.data[0].data[(j)] * m2.data[(i)].data[0] + m1.data[1].data[(j)] * m2.data[(i)].data[1] +
|
||||
m1.data[2].data[(j)] * m2.data[(i)].data[2]);
|
||||
};
|
||||
|
||||
return mat3(mul3(0, 0), mul3(0, 1), mul3(0, 2), mul3(1, 0), mul3(1, 1), mul3(1, 2), mul3(2, 0), mul3(2, 1), mul3(2, 2));
|
||||
|
||||
//#undef MUL3
|
||||
}
|
||||
|
||||
MAT3_DECL vec3 operator*(const mat3& m, const vec3& v)
|
||||
{
|
||||
return vec3(m.data[0].x * v.x + m.data[1].x * v.y + m.data[2].x * v.z, m.data[0].y * v.x + m.data[1].y * v.y + m.data[2].y * v.z,
|
||||
m.data[0].z * v.x + m.data[1].z * v.y + m.data[2].z * v.z);
|
||||
}
|
||||
|
||||
MAT3_DECL vec3 operator*(const vec3& v, const mat3& m)
|
||||
{
|
||||
return vec3(m.data[0].x * v.x + m.data[0].y * v.y + m.data[0].z * v.z, m.data[1].x * v.x + m.data[1].y * v.y + m.data[1].z * v.z,
|
||||
m.data[2].x * v.x + m.data[2].y * v.y + m.data[2].z * v.z);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator/(const mat3& m, float s)
|
||||
{
|
||||
return mat3(m.data[0].x / s, m.data[0].y / s, m.data[0].z / s, m.data[1].x / s, m.data[1].y / s, m.data[1].z / s, m.data[2].x / s,
|
||||
m.data[2].y / s, m.data[2].z / s);
|
||||
}
|
||||
|
||||
MAT3_DECL mat3 operator/(float s, const mat3& m)
|
||||
{
|
||||
return mat3(s / m.data[0].x, s / m.data[0].y, s / m.data[0].z, s / m.data[1].x, s / m.data[1].y, s / m.data[1].z, s / m.data[2].x,
|
||||
s / m.data[2].y, s / m.data[2].z);
|
||||
}
|
||||
|
||||
MAT3_DECL bool operator==(const mat3& m1, const mat3& m2)
|
||||
{
|
||||
return (m1.data[0].x == m2.data[0].x) && (m1.data[0].y == m2.data[0].y) && (m1.data[0].z == m2.data[0].z) &&
|
||||
(m1.data[1].x == m2.data[1].x) && (m1.data[1].y == m2.data[1].y) && (m1.data[1].z == m2.data[1].z) &&
|
||||
(m1.data[2].x == m2.data[2].x) && (m1.data[2].y == m2.data[2].y) && (m1.data[2].z == m2.data[2].z);
|
||||
}
|
||||
|
||||
MAT3_DECL bool operator!=(const mat3& m1, const mat3& m2)
|
||||
{
|
||||
return (m1.data[0].x != m2.data[0].x) || (m1.data[0].y != m2.data[0].y) || (m1.data[0].z != m2.data[0].z) ||
|
||||
(m1.data[1].x != m2.data[1].x) || (m1.data[1].y != m2.data[1].y) || (m1.data[1].z != m2.data[1].z) ||
|
||||
(m1.data[2].x != m2.data[2].x) || (m1.data[2].y != m2.data[2].y) || (m1.data[2].z != m2.data[2].z);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_MAT3IMPL_H_ */
|
||||
@@ -0,0 +1,389 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_MAT4IMPL_H_
|
||||
#define INCLUDE_KYTY_MATH_MAT4IMPL_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
// MAT4_DECL mat4::mat4() = default;
|
||||
//
|
||||
// MAT4_DECL mat4::mat4(const mat4 &m)
|
||||
//{
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y; data[0].z = m.data[0].z; data[0].w = m.data[0].w;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y; data[1].z = m.data[1].z; data[1].w = m.data[1].w;
|
||||
// data[2].x = m.data[2].x; data[2].y = m.data[2].y; data[2].z = m.data[2].z; data[2].w = m.data[2].w;
|
||||
// data[3].x = m.data[3].x; data[3].y = m.data[3].y; data[3].z = m.data[3].z; data[3].w = m.data[3].w;
|
||||
//}
|
||||
//
|
||||
// MAT4_DECL mat4::mat4(mat4 &&m) noexcept
|
||||
//{
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y; data[0].z = m.data[0].z; data[0].w = m.data[0].w;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y; data[1].z = m.data[1].z; data[1].w = m.data[1].w;
|
||||
// data[2].x = m.data[2].x; data[2].y = m.data[2].y; data[2].z = m.data[2].z; data[2].w = m.data[2].w;
|
||||
// data[3].x = m.data[3].x; data[3].y = m.data[3].y; data[3].z = m.data[3].z; data[3].w = m.data[3].w;
|
||||
//}
|
||||
|
||||
MAT4_DECL mat4::mat4(float x) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
{
|
||||
data[0].x = x;
|
||||
data[0].y = 0;
|
||||
data[0].z = 0;
|
||||
data[0].w = 0;
|
||||
data[1].x = 0;
|
||||
data[1].y = x;
|
||||
data[1].z = 0;
|
||||
data[1].w = 0;
|
||||
data[2].x = 0;
|
||||
data[2].y = 0;
|
||||
data[2].z = x;
|
||||
data[2].w = 0;
|
||||
data[3].x = 0;
|
||||
data[3].y = 0;
|
||||
data[3].z = 0;
|
||||
data[3].w = x;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4::mat4(float x1, float y1, float z1, float w1, // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
float x2, float y2, float z2, float w2, float x3, float y3, float z3, float w3, float x4, float y4, float z4,
|
||||
float w4) noexcept
|
||||
{
|
||||
data[0].x = x1;
|
||||
data[0].y = y1;
|
||||
data[0].z = z1;
|
||||
data[0].w = w1;
|
||||
data[1].x = x2;
|
||||
data[1].y = y2;
|
||||
data[1].z = z2;
|
||||
data[1].w = w2;
|
||||
data[2].x = x3;
|
||||
data[2].y = y3;
|
||||
data[2].z = z3;
|
||||
data[2].w = w3;
|
||||
data[3].x = x4;
|
||||
data[3].y = y4;
|
||||
data[3].z = z4;
|
||||
data[3].w = w4;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
MAT4_DECL mat4::mat4(const vec4& v1, const vec4& v2, const vec4& v3, const vec4& v4) noexcept
|
||||
{
|
||||
data[0].x = v1.x;
|
||||
data[0].y = v1.y;
|
||||
data[0].z = v1.z;
|
||||
data[0].w = v1.w;
|
||||
data[1].x = v2.x;
|
||||
data[1].y = v2.y;
|
||||
data[1].z = v2.z;
|
||||
data[1].w = v2.w;
|
||||
data[2].x = v3.x;
|
||||
data[2].y = v3.y;
|
||||
data[2].z = v3.z;
|
||||
data[2].w = v3.w;
|
||||
data[3].x = v4.x;
|
||||
data[3].y = v4.y;
|
||||
data[3].z = v4.z;
|
||||
data[3].w = v4.w;
|
||||
}
|
||||
|
||||
MAT4_DECL vec4& mat4::operator[](int i)
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 4));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
MAT4_DECL const vec4& mat4::operator[](int i) const
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 4));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
// MAT4_DECL mat4 &mat4::operator = (const mat4 &m)
|
||||
//{
|
||||
// if (this != &m)
|
||||
// {
|
||||
// data[0].x = m.data[0].x; data[0].y = m.data[0].y; data[0].z = m.data[0].z; data[0].w = m.data[0].w;
|
||||
// data[1].x = m.data[1].x; data[1].y = m.data[1].y; data[1].z = m.data[1].z; data[1].w = m.data[1].w;
|
||||
// data[2].x = m.data[2].x; data[2].y = m.data[2].y; data[2].z = m.data[2].z; data[2].w = m.data[2].w;
|
||||
// data[3].x = m.data[3].x; data[3].y = m.data[3].y; data[3].z = m.data[3].z; data[3].w = m.data[3].w;
|
||||
// }
|
||||
// return *this;
|
||||
//}
|
||||
//
|
||||
// MAT4_DECL mat4 &mat4::operator = (mat4 &&m) noexcept
|
||||
//{
|
||||
// *this = m;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator+=(float s)
|
||||
{
|
||||
data[0].x += s;
|
||||
data[0].y += s;
|
||||
data[0].z += s;
|
||||
data[0].w += s;
|
||||
data[1].x += s;
|
||||
data[1].y += s;
|
||||
data[1].z += s;
|
||||
data[1].w += s;
|
||||
data[2].x += s;
|
||||
data[2].y += s;
|
||||
data[2].z += s;
|
||||
data[2].w += s;
|
||||
data[3].x += s;
|
||||
data[3].y += s;
|
||||
data[3].z += s;
|
||||
data[3].w += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator+=(const mat4& m)
|
||||
{
|
||||
data[0].x += m.data[0].x;
|
||||
data[0].y += m.data[0].y;
|
||||
data[0].z += m.data[0].z;
|
||||
data[0].w += m.data[0].w;
|
||||
data[1].x += m.data[1].x;
|
||||
data[1].y += m.data[1].y;
|
||||
data[1].z += m.data[1].z;
|
||||
data[1].w += m.data[1].w;
|
||||
data[2].x += m.data[2].x;
|
||||
data[2].y += m.data[2].y;
|
||||
data[2].z += m.data[2].z;
|
||||
data[2].w += m.data[2].w;
|
||||
data[3].x += m.data[3].x;
|
||||
data[3].y += m.data[3].y;
|
||||
data[3].z += m.data[3].z;
|
||||
data[3].w += m.data[3].w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator-=(float s)
|
||||
{
|
||||
data[0].x -= s;
|
||||
data[0].y -= s;
|
||||
data[0].z -= s;
|
||||
data[0].w -= s;
|
||||
data[1].x -= s;
|
||||
data[1].y -= s;
|
||||
data[1].z -= s;
|
||||
data[1].w -= s;
|
||||
data[2].x -= s;
|
||||
data[2].y -= s;
|
||||
data[2].z -= s;
|
||||
data[2].w -= s;
|
||||
data[3].x -= s;
|
||||
data[3].y -= s;
|
||||
data[3].z -= s;
|
||||
data[3].w -= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator-=(const mat4& m)
|
||||
{
|
||||
data[0].x -= m.data[0].x;
|
||||
data[0].y -= m.data[0].y;
|
||||
data[0].z -= m.data[0].z;
|
||||
data[0].w -= m.data[0].w;
|
||||
data[1].x -= m.data[1].x;
|
||||
data[1].y -= m.data[1].y;
|
||||
data[1].z -= m.data[1].z;
|
||||
data[1].w -= m.data[1].w;
|
||||
data[2].x -= m.data[2].x;
|
||||
data[2].y -= m.data[2].y;
|
||||
data[2].z -= m.data[2].z;
|
||||
data[2].w -= m.data[2].w;
|
||||
data[3].x -= m.data[3].x;
|
||||
data[3].y -= m.data[3].y;
|
||||
data[3].z -= m.data[3].z;
|
||||
data[3].w -= m.data[3].w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator*=(float s)
|
||||
{
|
||||
data[0].x *= s;
|
||||
data[0].y *= s;
|
||||
data[0].z *= s;
|
||||
data[0].w *= s;
|
||||
data[1].x *= s;
|
||||
data[1].y *= s;
|
||||
data[1].z *= s;
|
||||
data[1].w *= s;
|
||||
data[2].x *= s;
|
||||
data[2].y *= s;
|
||||
data[2].z *= s;
|
||||
data[2].w *= s;
|
||||
data[3].x *= s;
|
||||
data[3].y *= s;
|
||||
data[3].z *= s;
|
||||
data[3].w *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator*=(const mat4& m)
|
||||
{
|
||||
*this = *this * m;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4& mat4::operator/=(float s)
|
||||
{
|
||||
data[0].x /= s;
|
||||
data[0].y /= s;
|
||||
data[0].z /= s;
|
||||
data[0].w /= s;
|
||||
data[1].x /= s;
|
||||
data[1].y /= s;
|
||||
data[1].z /= s;
|
||||
data[1].w /= s;
|
||||
data[2].x /= s;
|
||||
data[2].y /= s;
|
||||
data[2].z /= s;
|
||||
data[2].w /= s;
|
||||
data[3].x /= s;
|
||||
data[3].y /= s;
|
||||
data[3].z /= s;
|
||||
data[3].w /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator+(const mat4& m, float s)
|
||||
{
|
||||
return mat4(m.data[0].x + s, m.data[0].y + s, m.data[0].z + s, m.data[0].w + s, m.data[1].x + s, m.data[1].y + s, m.data[1].z + s,
|
||||
m.data[1].w + s, m.data[2].x + s, m.data[2].y + s, m.data[2].z + s, m.data[2].w + s, m.data[3].x + s, m.data[3].y + s,
|
||||
m.data[3].z + s, m.data[3].w + s);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator+(float s, const mat4& m)
|
||||
{
|
||||
return mat4(m.data[0].x + s, m.data[0].y + s, m.data[0].z + s, m.data[0].w + s, m.data[1].x + s, m.data[1].y + s, m.data[1].z + s,
|
||||
m.data[1].w + s, m.data[2].x + s, m.data[2].y + s, m.data[2].z + s, m.data[2].w + s, m.data[3].x + s, m.data[3].y + s,
|
||||
m.data[3].z + s, m.data[3].w + s);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator+(const mat4& m1, const mat4& m2)
|
||||
{
|
||||
return mat4(m1.data[0].x + m2.data[0].x, m1.data[0].y + m2.data[0].y, m1.data[0].z + m2.data[0].z, m1.data[0].w + m2.data[0].w,
|
||||
m1.data[1].x + m2.data[1].x, m1.data[1].y + m2.data[1].y, m1.data[1].z + m2.data[1].z, m1.data[1].w + m2.data[1].w,
|
||||
m1.data[2].x + m2.data[2].x, m1.data[2].y + m2.data[2].y, m1.data[2].z + m2.data[2].z, m1.data[2].w + m2.data[2].w,
|
||||
m1.data[3].x + m2.data[3].x, m1.data[3].y + m2.data[3].y, m1.data[3].z + m2.data[3].z, m1.data[3].w + m2.data[3].w);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator-(const mat4& m, float s)
|
||||
{
|
||||
return mat4(m.data[0].x - s, m.data[0].y - s, m.data[0].z - s, m.data[0].w - s, m.data[1].x - s, m.data[1].y - s, m.data[1].z - s,
|
||||
m.data[1].w - s, m.data[2].x - s, m.data[2].y - s, m.data[2].z - s, m.data[2].w - s, m.data[3].x - s, m.data[3].y - s,
|
||||
m.data[3].z - s, m.data[3].w - s);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator-(float s, const mat4& m)
|
||||
{
|
||||
return mat4(s - m.data[0].x, s - m.data[0].y, s - m.data[0].z, s - m.data[0].w, s - m.data[1].x, s - m.data[1].y, s - m.data[1].z,
|
||||
s - m.data[1].w, s - m.data[2].x, s - m.data[2].y, s - m.data[2].z, s - m.data[2].w, s - m.data[3].x, s - m.data[3].y,
|
||||
s - m.data[3].z, s - m.data[3].w);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator-(const mat4& m1, const mat4& m2)
|
||||
{
|
||||
return mat4(m1.data[0].x - m2.data[0].x, m1.data[0].y - m2.data[0].y, m1.data[0].z - m2.data[0].z, m1.data[0].w - m2.data[0].w,
|
||||
m1.data[1].x - m2.data[1].x, m1.data[1].y - m2.data[1].y, m1.data[1].z - m2.data[1].z, m1.data[1].w - m2.data[1].w,
|
||||
m1.data[2].x - m2.data[2].x, m1.data[2].y - m2.data[2].y, m1.data[2].z - m2.data[2].z, m1.data[2].w - m2.data[2].w,
|
||||
m1.data[3].x - m2.data[3].x, m1.data[3].y - m2.data[3].y, m1.data[3].z - m2.data[3].z, m1.data[3].w - m2.data[3].w);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator*(const mat4& m, float s)
|
||||
{
|
||||
return mat4(m.data[0].x * s, m.data[0].y * s, m.data[0].z * s, m.data[0].w * s, m.data[1].x * s, m.data[1].y * s, m.data[1].z * s,
|
||||
m.data[1].w * s, m.data[2].x * s, m.data[2].y * s, m.data[2].z * s, m.data[2].w * s, m.data[3].x * s, m.data[3].y * s,
|
||||
m.data[3].z * s, m.data[3].w * s);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator*(float s, const mat4& m)
|
||||
{
|
||||
return mat4(m.data[0].x * s, m.data[0].y * s, m.data[0].z * s, m.data[0].w * s, m.data[1].x * s, m.data[1].y * s, m.data[1].z * s,
|
||||
m.data[1].w * s, m.data[2].x * s, m.data[2].y * s, m.data[2].z * s, m.data[2].w * s, m.data[3].x * s, m.data[3].y * s,
|
||||
m.data[3].z * s, m.data[3].w * s);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator*(const mat4& m1, const mat4& m2)
|
||||
{
|
||||
/*#define MUL4(i, j)*/ auto mul4 = [&](auto i, auto j) {
|
||||
return (m1.data[0].data[(j)] * m2.data[(i)].data[0] + m1.data[1].data[(j)] * m2.data[(i)].data[1] +
|
||||
m1.data[2].data[(j)] * m2.data[(i)].data[2] + m1.data[3].data[(j)] * m2.data[(i)].data[3]);
|
||||
};
|
||||
|
||||
return mat4(mul4(0, 0), mul4(0, 1), mul4(0, 2), mul4(0, 3), mul4(1, 0), mul4(1, 1), mul4(1, 2), mul4(1, 3), mul4(2, 0), mul4(2, 1),
|
||||
mul4(2, 2), mul4(2, 3), mul4(3, 0), mul4(3, 1), mul4(3, 2), mul4(3, 3));
|
||||
|
||||
//#undef MUL4
|
||||
}
|
||||
|
||||
MAT4_DECL vec4 operator*(const mat4& m, const vec4& v)
|
||||
{
|
||||
float x1 = m.data[0].x * v.x + m.data[1].x * v.y;
|
||||
float x2 = m.data[2].x * v.z + m.data[3].x * v.w;
|
||||
float y1 = m.data[0].y * v.x + m.data[1].y * v.y;
|
||||
float y2 = m.data[2].y * v.z + m.data[3].y * v.w;
|
||||
float z1 = m.data[0].z * v.x + m.data[1].z * v.y;
|
||||
float z2 = m.data[2].z * v.z + m.data[3].z * v.w;
|
||||
float w1 = m.data[0].w * v.x + m.data[1].w * v.y;
|
||||
float w2 = m.data[2].w * v.z + m.data[3].w * v.w;
|
||||
|
||||
return vec4(x1 + x2, y1 + y2, z1 + z2, w1 + w2);
|
||||
|
||||
// return vec4(m.data[0].x * v.x + m.data[1].x * v.y + m.data[2].x * v.z + m.data[3].x * v.w,
|
||||
// m.data[0].y * v.x + m.data[1].y * v.y + m.data[2].y * v.z + m.data[3].y * v.w,
|
||||
// m.data[0].z * v.x + m.data[1].z * v.y + m.data[2].z * v.z + m.data[3].z * v.w,
|
||||
// m.data[0].w * v.x + m.data[1].w * v.y + m.data[2].w * v.z + m.data[3].w * v.w);
|
||||
}
|
||||
|
||||
MAT4_DECL vec4 operator*(const vec4& v, const mat4& m)
|
||||
{
|
||||
return vec4(m.data[0].x * v.x + m.data[0].y * v.y + m.data[0].z * v.z + m.data[0].w * v.w,
|
||||
m.data[1].x * v.x + m.data[1].y * v.y + m.data[1].z * v.z + m.data[1].w * v.w,
|
||||
m.data[2].x * v.x + m.data[2].y * v.y + m.data[2].z * v.z + m.data[2].w * v.w,
|
||||
m.data[3].x * v.x + m.data[3].y * v.y + m.data[3].z * v.z + m.data[3].w * v.w);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator/(const mat4& m, float s)
|
||||
{
|
||||
return mat4(m.data[0].x / s, m.data[0].y / s, m.data[0].z / s, m.data[0].w / s, m.data[1].x / s, m.data[1].y / s, m.data[1].z / s,
|
||||
m.data[1].w / s, m.data[2].x / s, m.data[2].y / s, m.data[2].z / s, m.data[2].w / s, m.data[3].x / s, m.data[3].y / s,
|
||||
m.data[3].z / s, m.data[3].w / s);
|
||||
}
|
||||
|
||||
MAT4_DECL mat4 operator/(float s, const mat4& m)
|
||||
{
|
||||
return mat4(s / m.data[0].x, s / m.data[0].y, s / m.data[0].z, s / m.data[0].w, s / m.data[1].x, s / m.data[1].y, s / m.data[1].z,
|
||||
s / m.data[1].w, s / m.data[2].x, s / m.data[2].y, s / m.data[2].z, s / m.data[2].w, s / m.data[3].x, s / m.data[3].y,
|
||||
s / m.data[3].z, s / m.data[3].w);
|
||||
}
|
||||
|
||||
MAT4_DECL bool operator==(const mat4& m1, const mat4& m2)
|
||||
{
|
||||
return (m1.data[0].x == m2.data[0].x) && (m1.data[0].y == m2.data[0].y) && (m1.data[0].z == m2.data[0].z) &&
|
||||
(m1.data[0].w == m2.data[0].w) && (m1.data[1].x == m2.data[1].x) && (m1.data[1].y == m2.data[1].y) &&
|
||||
(m1.data[1].z == m2.data[1].z) && (m1.data[1].w == m2.data[1].w) && (m1.data[2].x == m2.data[2].x) &&
|
||||
(m1.data[2].y == m2.data[2].y) && (m1.data[2].z == m2.data[2].z) && (m1.data[2].w == m2.data[2].w) &&
|
||||
(m1.data[3].x == m2.data[3].x) && (m1.data[3].y == m2.data[3].y) && (m1.data[3].z == m2.data[3].z) &&
|
||||
(m1.data[3].w == m2.data[3].w);
|
||||
}
|
||||
|
||||
MAT4_DECL bool operator!=(const mat4& m1, const mat4& m2)
|
||||
{
|
||||
return (m1.data[0].x != m2.data[0].x) || (m1.data[0].y != m2.data[0].y) || (m1.data[0].z != m2.data[0].z) ||
|
||||
(m1.data[0].w != m2.data[0].w) || (m1.data[1].x != m2.data[1].x) || (m1.data[1].y != m2.data[1].y) ||
|
||||
(m1.data[1].z != m2.data[1].z) || (m1.data[1].w != m2.data[1].w) || (m1.data[2].x != m2.data[2].x) ||
|
||||
(m1.data[2].y != m2.data[2].y) || (m1.data[2].z != m2.data[2].z) || (m1.data[2].w != m2.data[2].w) ||
|
||||
(m1.data[3].x != m2.data[3].x) || (m1.data[3].y != m2.data[3].y) || (m1.data[3].z != m2.data[3].z) ||
|
||||
(m1.data[3].w != m2.data[3].w);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_MAT4IMPL_H_ */
|
||||
@@ -0,0 +1,522 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_MATHALL_H_
|
||||
#define INCLUDE_KYTY_MATH_MATHALL_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
//#define KYTY_MATH_GLM
|
||||
|
||||
#ifdef KYTY_MATH_GLM
|
||||
#include "Kyty/KytyGlmInc.h" // IWYU pragma: export
|
||||
typedef glm::mat2 mat2;
|
||||
typedef glm::mat3 mat3;
|
||||
typedef glm::mat4 mat4;
|
||||
typedef glm::vec2 vec2;
|
||||
typedef glm::vec3 vec3;
|
||||
typedef glm::vec4 vec4;
|
||||
#else
|
||||
#include "Kyty/Math/VectorAndMatrix.h" // IWYU pragma: export
|
||||
using mat2 = Kyty::Math::m::mat2;
|
||||
using mat3 = Kyty::Math::m::mat3;
|
||||
using mat4 = Kyty::Math::m::mat4;
|
||||
using vec2 = Kyty::Math::m::vec2;
|
||||
using vec3 = Kyty::Math::m::vec3;
|
||||
using vec4 = Kyty::Math::m::vec4;
|
||||
#endif
|
||||
|
||||
namespace Kyty::Math {
|
||||
|
||||
namespace Double {
|
||||
constexpr double E = 2.7182818284590452354; /* e */
|
||||
constexpr double LOG2E = 1.4426950408889634074; /* log 2e */
|
||||
constexpr double LOG10E = 0.43429448190325182765; /* log 10e */
|
||||
constexpr double LN2 = 0.69314718055994530942; /* log e2 */
|
||||
constexpr double LN10 = 2.30258509299404568402; /* log e10 */
|
||||
constexpr double PI = 3.14159265358979323846; /* pi */
|
||||
constexpr double PI_2 = 1.57079632679489661923; /* pi/2 */
|
||||
constexpr double PI_4 = 0.78539816339744830962; /* pi/4 */
|
||||
constexpr double C_1_PI = 0.31830988618379067154; /* 1/pi */
|
||||
constexpr double C_2_PI = 0.63661977236758134308; /* 2/pi */
|
||||
constexpr double C_2_SQRTPI = 1.12837916709551257390; /* 2/sqrt(pi) */
|
||||
constexpr double SQRT2 = 1.41421356237309504880; /* sqrt(2) */
|
||||
constexpr double SQRT1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
|
||||
} // namespace Double
|
||||
|
||||
namespace Float {
|
||||
constexpr float E = 2.7182818284590452354f; /* e */
|
||||
constexpr float LOG2E = 1.4426950408889634074f; /* log 2e */
|
||||
constexpr float LOG10E = 0.43429448190325182765f; /* log 10e */
|
||||
constexpr float LN2 = 0.69314718055994530942f; /* log e2 */
|
||||
constexpr float LN10 = 2.30258509299404568402f; /* log e10 */
|
||||
constexpr float PI = 3.14159265358979323846f; /* pi */
|
||||
constexpr float PI_2 = 1.57079632679489661923f; /* pi/2 */
|
||||
constexpr float PI_4 = 0.78539816339744830962f; /* pi/4 */
|
||||
constexpr float C_1_PI = 0.31830988618379067154f; /* 1/pi */
|
||||
constexpr float C_2_PI = 0.63661977236758134308f; /* 2/pi */
|
||||
constexpr float C_2_SQRTPI = 1.12837916709551257390f; /* 2/sqrt(pi) */
|
||||
constexpr float SQRT2 = 1.41421356237309504880f; /* sqrt(2) */
|
||||
constexpr float SQRT1_2 = 0.70710678118654752440f; /* 1/sqrt(2) */
|
||||
} // namespace Float
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Math);
|
||||
|
||||
inline vec3& xyz(vec4& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return *(vec3*)glm::value_ptr(v);
|
||||
#else
|
||||
return *reinterpret_cast<vec3*>(m::value_ptr(v));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline const vec3& xyz(const vec4& v)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return *(const vec3*)glm::value_ptr(v);
|
||||
#else
|
||||
return *reinterpret_cast<const vec3*>(m::value_ptr(v));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec2& xy(vec4& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return *(vec2*)glm::value_ptr(v);
|
||||
#else
|
||||
return *reinterpret_cast<vec2*>(m::value_ptr(v));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec2& xy(vec3& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return *(vec2*)glm::value_ptr(v);
|
||||
#else
|
||||
return *reinterpret_cast<vec2*>(m::value_ptr(v));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t nod(uint32_t a, uint32_t b)
|
||||
{
|
||||
while ((a != 0u) && (b != 0u))
|
||||
{
|
||||
a > b ? a %= b : b %= a;
|
||||
}
|
||||
return a + b;
|
||||
}
|
||||
|
||||
struct Size
|
||||
{
|
||||
Size() = default;
|
||||
Size(uint32_t w, uint32_t h): width(w), height(h) {}
|
||||
|
||||
bool operator==(const Size& s) const { return width == s.width && height == s.height; }
|
||||
|
||||
uint32_t width {0};
|
||||
uint32_t height {0};
|
||||
};
|
||||
|
||||
struct Rect
|
||||
{
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
inline mat4 mat_translate(const vec3& v)
|
||||
{
|
||||
return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, v.x, v.y, v.z, 1.0f);
|
||||
}
|
||||
|
||||
inline mat4 mat_translate(const vec2& v)
|
||||
{
|
||||
return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, v.x, v.y, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
inline mat4 mat_translate(float z)
|
||||
{
|
||||
return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, z, 1.0f);
|
||||
}
|
||||
|
||||
inline void mat_translate_upd(mat4& m, const vec3& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
m[3][0] = v.x;
|
||||
m[3][1] = v.y;
|
||||
m[3][2] = v.z;
|
||||
}
|
||||
|
||||
inline void mat_translate_upd(mat4& m, const vec2& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
m[3][0] = v.x;
|
||||
m[3][1] = v.y;
|
||||
}
|
||||
|
||||
inline void mat_translate_upd(mat4& m, float z) // NOLINT(google-runtime-references)
|
||||
{
|
||||
m[3][2] = z;
|
||||
}
|
||||
|
||||
inline mat4 mat_scale(const vec3& v)
|
||||
{
|
||||
return mat4(v.x, 0.0f, 0.0f, 0.0f, 0.0f, v.y, 0.0f, 0.0f, 0.0f, 0.0f, v.z, 0.0f, 0.0f, 0.0f, 0.0, 1.0f);
|
||||
}
|
||||
|
||||
inline mat4 mat_scale(const vec2& v)
|
||||
{
|
||||
return mat4(v.x, 0.0f, 0.0f, 0.0f, 0.0f, v.y, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0, 1.0f);
|
||||
}
|
||||
|
||||
inline void mat_scale_upd(mat4& m, const vec3& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
m[0][0] = v.x;
|
||||
m[1][1] = v.y;
|
||||
m[2][2] = v.z;
|
||||
}
|
||||
|
||||
inline void mat_scale_upd(mat4& m, const vec2& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
m[0][0] = v.x;
|
||||
m[1][1] = v.y;
|
||||
}
|
||||
|
||||
inline mat4 mat_rotate(float angle, const vec3& v)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::rotate(mat4(1.0f), angle, v);
|
||||
#else
|
||||
return m::rotate(angle, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 mat_rotate(float angle)
|
||||
{
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
return mat4(c, s, 0.0f, 0.0f, -s, c, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0, 1.0f);
|
||||
}
|
||||
|
||||
inline void mat_rotate_upd(mat4& m, float angle, const vec3& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
m = glm::rotate(mat4(1.0f), angle, v);
|
||||
#else
|
||||
m = m::rotate(angle, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void mat_rotate_upd(mat4& m, float angle) // NOLINT(google-runtime-references)
|
||||
{
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
m[0][0] = c;
|
||||
m[1][1] = c;
|
||||
m[1][0] = -s;
|
||||
m[0][1] = s;
|
||||
}
|
||||
|
||||
inline vec2 vec_reciprocal(const vec2& v)
|
||||
{
|
||||
EXIT_IF(v.x == 0.0f || v.y == 0.0f);
|
||||
|
||||
return vec2(1.0f / v.x, 1.0f / v.y);
|
||||
}
|
||||
|
||||
inline vec3 vec_reciprocal(const vec3& v)
|
||||
{
|
||||
EXIT_IF(v.x == 0.0f || v.y == 0.0f || v.z == 0.0f);
|
||||
|
||||
return vec3(1.0f / v.x, 1.0f / v.y, 1.0f / v.z);
|
||||
}
|
||||
|
||||
inline vec4 vec_reciprocal(const vec4& v)
|
||||
{
|
||||
EXIT_IF(v.x == 0.0f || v.y == 0.0f || v.z == 0.0f || v.w == 0.0f);
|
||||
|
||||
return vec4(1.0f / v.x, 1.0f / v.y, 1.0f / v.z, 1.0f / v.w);
|
||||
}
|
||||
|
||||
struct PosUV
|
||||
{
|
||||
vec2 pos {};
|
||||
vec2 uv {};
|
||||
};
|
||||
|
||||
struct RectUV
|
||||
{
|
||||
PosUV p1 {};
|
||||
PosUV p2 {};
|
||||
float z {};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T floordiv(T a, T b)
|
||||
{
|
||||
if (b < 0)
|
||||
{
|
||||
if (a < 0)
|
||||
{
|
||||
return a / b;
|
||||
};
|
||||
b = -b;
|
||||
a = -a;
|
||||
}
|
||||
|
||||
return (a - (a < 0 ? b - 1 : 0)) / b;
|
||||
}
|
||||
|
||||
inline mat4 mat_lookAt(const vec3& eye, const vec3& center, const vec3& up)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::lookAt(eye, center, up);
|
||||
#else
|
||||
return m::lookAt(eye, center, up);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 mat_perspective(float f, float a, float nr, float fr)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::perspective(f, a, nr, fr);
|
||||
#else
|
||||
return m::perspective(f, a, nr, fr);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 mat_ortho(float left, float right, float bottom, float top, float z_near, float z_far)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::ortho(left, right, bottom, top, z_near, z_far);
|
||||
#else
|
||||
return m::ortho(left, right, bottom, top, z_near, z_far);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 mat_inverse_transpose(const mat4& m)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::inverseTranspose(m);
|
||||
#else
|
||||
return m::inverseTranspose(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 mat_transpose(const mat4& m)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::transpose(m);
|
||||
#else
|
||||
return m::transpose(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 mat_inverse(const mat4& m)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::inverse(m);
|
||||
#else
|
||||
return m::inverse(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat3 mat_transpose(const mat3& m)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::transpose(m);
|
||||
#else
|
||||
return m::transpose(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat3 mat_inverse(const mat3& m)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::inverse(m);
|
||||
#else
|
||||
return m::inverse(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline mat4 make_mat4(const float* f)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::make_mat4(f);
|
||||
#else
|
||||
return m::make_mat4(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_radians(float a)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::radians(a);
|
||||
#else
|
||||
return m::radians(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_round(float a)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::round(a);
|
||||
#else
|
||||
return m::round(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec4 math_round(const vec4& a)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::round(a);
|
||||
#else
|
||||
return m::round(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_max(float a, float b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::max(a, b);
|
||||
#else
|
||||
return m::max(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec2 math_max(const vec2& a, const vec2& b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::max(a, b);
|
||||
#else
|
||||
return m::max(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec3 math_max(const vec3& a, const vec3& b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::max(a, b);
|
||||
#else
|
||||
return m::max(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec4 math_max(const vec4& a, const vec4& b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::max(a, b);
|
||||
#else
|
||||
return m::max(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_min(float a, float b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::min(a, b);
|
||||
#else
|
||||
return m::min(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec2 math_min(const vec2& a, const vec2& b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::min(a, b);
|
||||
#else
|
||||
return m::min(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec3 math_min(const vec3& a, const vec3& b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::min(a, b);
|
||||
#else
|
||||
return m::min(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec4 math_min(const vec4& a, const vec4& b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::min(a, b);
|
||||
#else
|
||||
return m::min(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_clamp(float v, float a, float b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::clamp(v, a, b);
|
||||
#else
|
||||
return m::clamp(v, a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec3 math_clamp(const vec3& v, float a, float b)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::clamp(v, a, b);
|
||||
#else
|
||||
return m::clamp(v, a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_abs(float v)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::abs(v);
|
||||
#else
|
||||
return m::abs(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline vec2 math_abs(const vec2& v)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::abs(v);
|
||||
#else
|
||||
return m::abs(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float math_dot(const vec2& x, const vec2& y)
|
||||
{
|
||||
#ifdef KYTY_MATH_GLM
|
||||
return glm::dot(x, y);
|
||||
#else
|
||||
return m::dot(x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int math_nod(int a, int b)
|
||||
{
|
||||
while ((a != 0) && (b != 0))
|
||||
{
|
||||
a > b ? a %= b : b %= a;
|
||||
}
|
||||
return a + b;
|
||||
}
|
||||
|
||||
inline int math_nod(int a, int b, int c)
|
||||
{
|
||||
return static_cast<int>(nod(nod(a, b), c));
|
||||
}
|
||||
|
||||
inline int math_nod(int* a, int n)
|
||||
{
|
||||
int d = a[0];
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
d = static_cast<int>(nod(d, a[i]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_MATHALL_H_ */
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_RAND_H_
|
||||
#define INCLUDE_KYTY_MATH_RAND_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include <random> // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Math {
|
||||
|
||||
class Rand
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
// random in range [0, 4294967295]
|
||||
static uint32_t Uint();
|
||||
|
||||
// random in range [-2147483648, 2147483647]
|
||||
static int32_t Int();
|
||||
|
||||
// random in range [0.0, 1.0]
|
||||
static double DoubleInclusive();
|
||||
|
||||
// random in range [0.0, 1.0)
|
||||
static double Double();
|
||||
|
||||
// random in range [from, to]
|
||||
static double DoubleInclusiveRange(double from_incl, double to_incl);
|
||||
|
||||
// random in range [from, to)
|
||||
static double DoubleRange(double from_incl, double to_excl);
|
||||
|
||||
// random in range [0.0, 1.0]
|
||||
static float FloatInclusive();
|
||||
|
||||
// random in range [0.0, 1.0)
|
||||
static float Float();
|
||||
|
||||
// random in range [from, to]
|
||||
static float FloatInclusiveRange(float from_incl, float to_incl);
|
||||
|
||||
// random in range [from, to)
|
||||
static float FloatRange(float from_incl, float to_excl);
|
||||
|
||||
// random in range [from, to]
|
||||
static uint32_t UintInclusiveRange(uint32_t from_incl, uint32_t to_incl);
|
||||
|
||||
// random in range [from, to]
|
||||
static int32_t IntInclusiveRange(int32_t from_incl, int32_t to_incl);
|
||||
|
||||
static void Seed(unsigned int s);
|
||||
|
||||
static void SeedBySystemTime();
|
||||
|
||||
static std::mt19937 GetRandomEngine();
|
||||
};
|
||||
|
||||
// using Rand = Math::Rand;
|
||||
|
||||
} // namespace Kyty::Math
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_RAND_H_ */
|
||||
@@ -0,0 +1,181 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_VEC2IMPL_H_
|
||||
#define INCLUDE_KYTY_MATH_VEC2IMPL_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
// VEC2_DECL vec2::vec2() {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
// VEC2_DECL vec2::vec2(const vec2 &v): x(v.x), y(v.y) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
// VEC2_DECL vec2::vec2(vec2 &&v) noexcept: x(v.x), y(v.y) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC2_DECL vec2::vec2(const vec3& v) noexcept: x(v.x), y(v.y) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC2_DECL vec2::vec2(const vec4& v) noexcept: x(v.x), y(v.y) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC2_DECL vec2::vec2(float s) noexcept: x(s), y(s) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC2_DECL vec2::vec2(float s1, float s2) noexcept: x(s1), y(s2) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
|
||||
VEC2_DECL float& vec2::operator[](int i)
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 2));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
VEC2_DECL float const& vec2::operator[](int i) const
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 2));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
// VEC2_DECL vec2 &vec2::operator = (const vec2 &v)
|
||||
//{
|
||||
// if (this != &v)
|
||||
// {
|
||||
// x = v.x;
|
||||
// y = v.y;
|
||||
// }
|
||||
// return *this;
|
||||
//}
|
||||
//
|
||||
// VEC2_DECL vec2 &vec2::operator = (vec2 &&v) noexcept
|
||||
//{
|
||||
// *this = v;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator+=(float s)
|
||||
{
|
||||
x += s;
|
||||
y += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator+=(const vec2& v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator-=(float s)
|
||||
{
|
||||
x -= s;
|
||||
y -= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator-=(const vec2& v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator*=(float s)
|
||||
{
|
||||
x *= s;
|
||||
y *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator*=(const vec2& v)
|
||||
{
|
||||
x *= v.x;
|
||||
y *= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator/=(float s)
|
||||
{
|
||||
x /= s;
|
||||
y /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2& vec2::operator/=(const vec2& v)
|
||||
{
|
||||
x /= v.x;
|
||||
y /= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 vec2::operator-() const
|
||||
{
|
||||
return vec2(-x, -y);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator+(const vec2& v, float s)
|
||||
{
|
||||
return vec2(v.x + s, v.y + s);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator+(float s, const vec2& v)
|
||||
{
|
||||
return vec2(v.x + s, v.y + s);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator+(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return vec2(v1.x + v2.x, v1.y + v2.y);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator-(const vec2& v, float s)
|
||||
{
|
||||
return vec2(v.x - s, v.y - s);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator-(float s, const vec2& v)
|
||||
{
|
||||
return vec2(s - v.x, s - v.y);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator-(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return vec2(v1.x - v2.x, v1.y - v2.y);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator*(const vec2& v, float s)
|
||||
{
|
||||
return vec2(v.x * s, v.y * s);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator*(float s, const vec2& v)
|
||||
{
|
||||
return vec2(v.x * s, v.y * s);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator*(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return vec2(v1.x * v2.x, v1.y * v2.y);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator/(const vec2& v, float s)
|
||||
{
|
||||
return vec2(v.x / s, v.y / s);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator/(float s, const vec2& v)
|
||||
{
|
||||
return vec2(s / v.x, s / v.y);
|
||||
}
|
||||
|
||||
VEC2_DECL vec2 operator/(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return vec2(v1.x / v2.x, v1.y / v2.y);
|
||||
}
|
||||
|
||||
VEC2_DECL bool operator==(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return (v1.x == v2.x) && (v1.y == v2.y);
|
||||
}
|
||||
|
||||
VEC2_DECL bool operator!=(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return (v1.x != v2.x) || (v1.y != v2.y);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_VEC2IMPL_H_ */
|
||||
@@ -0,0 +1,191 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_VEC3IMPL_H_
|
||||
#define INCLUDE_KYTY_MATH_VEC3IMPL_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC3_DECL vec3::vec3(const vec4& v) noexcept: x(v.x), y(v.y), z(v.z) {}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC3_DECL vec3::vec3(float s) noexcept: x(s), y(s), z(s) {}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC3_DECL vec3::vec3(float s1, float s2, float s3) noexcept: x(s1), y(s2), z(s3) {}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC3_DECL vec3::vec3(const vec2& v, float s3) noexcept: x(v.x), y(v.y), z(s3) {}
|
||||
|
||||
VEC3_DECL float& vec3::operator[](int i)
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 3));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
VEC3_DECL float const& vec3::operator[](int i) const
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 3));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
// VEC3_DECL vec3 &vec3::operator = (const vec3 &v)
|
||||
//{
|
||||
// if (this != &v)
|
||||
// {
|
||||
// x = v.x;
|
||||
// y = v.y;
|
||||
// z = v.z;
|
||||
// }
|
||||
// return *this;
|
||||
//}
|
||||
//
|
||||
// VEC3_DECL vec3 &vec3::operator = (vec3 &&v) noexcept
|
||||
//{
|
||||
// *this = v;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator+=(float s)
|
||||
{
|
||||
x += s;
|
||||
y += s;
|
||||
z += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator+=(const vec3& v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator-=(float s)
|
||||
{
|
||||
x -= s;
|
||||
y -= s;
|
||||
z -= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator-=(const vec3& v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator*=(float s)
|
||||
{
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator*=(const vec3& v)
|
||||
{
|
||||
x *= v.x;
|
||||
y *= v.y;
|
||||
z *= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator/=(float s)
|
||||
{
|
||||
x /= s;
|
||||
y /= s;
|
||||
z /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3& vec3::operator/=(const vec3& v)
|
||||
{
|
||||
x /= v.x;
|
||||
y /= v.y;
|
||||
z /= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 vec3::operator-() const
|
||||
{
|
||||
return vec3(-x, -y, -z);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator+(const vec3& v, float s)
|
||||
{
|
||||
return vec3(v.x + s, v.y + s, v.z + s);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator+(float s, const vec3& v)
|
||||
{
|
||||
return vec3(v.x + s, v.y + s, v.z + s);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator+(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator-(const vec3& v, float s)
|
||||
{
|
||||
return vec3(v.x - s, v.y - s, v.z - s);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator-(float s, const vec3& v)
|
||||
{
|
||||
return vec3(s - v.x, s - v.y, s - v.z);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator-(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return vec3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator*(const vec3& v, float s)
|
||||
{
|
||||
return vec3(v.x * s, v.y * s, v.z * s);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator*(float s, const vec3& v)
|
||||
{
|
||||
return vec3(v.x * s, v.y * s, v.z * s);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator*(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return vec3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator/(const vec3& v, float s)
|
||||
{
|
||||
return vec3(v.x / s, v.y / s, v.z / s);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator/(float s, const vec3& v)
|
||||
{
|
||||
return vec3(s / v.x, s / v.y, s / v.z);
|
||||
}
|
||||
|
||||
VEC3_DECL vec3 operator/(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return vec3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
|
||||
}
|
||||
|
||||
VEC3_DECL bool operator==(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z);
|
||||
}
|
||||
|
||||
VEC3_DECL bool operator!=(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_VEC3IMPL_H_ */
|
||||
@@ -0,0 +1,198 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_VEC4IMPL_H_
|
||||
#define INCLUDE_KYTY_MATH_VEC4IMPL_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC4_DECL vec4::vec4(float s) noexcept: x(s), y(s), z(s), w(s) {}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC4_DECL vec4::vec4(float s1, float s2, float s3, float s4) noexcept: x(s1), y(s2), z(s3), w(s4) {}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
VEC4_DECL vec4::vec4(const vec3& v, float s4) noexcept: x(v.x), y(v.y), z(v.z), w(s4) {}
|
||||
|
||||
VEC4_DECL float& vec4::operator[](int i)
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 4));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
VEC4_DECL float const& vec4::operator[](int i) const
|
||||
{
|
||||
EXIT_IF(!(i >= 0 && i < 4));
|
||||
|
||||
return data[i];
|
||||
}
|
||||
|
||||
// VEC4_DECL vec4 &vec4::operator = (const vec4 &v)
|
||||
//{
|
||||
// if (this != &v)
|
||||
// {
|
||||
// x = v.x;
|
||||
// y = v.y;
|
||||
// z = v.z;
|
||||
// w = v.w;
|
||||
// }
|
||||
// return *this;
|
||||
//}
|
||||
//
|
||||
// VEC4_DECL vec4 &vec4::operator = (vec4 &&v) noexcept
|
||||
//{
|
||||
// *this = v;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator+=(float s)
|
||||
{
|
||||
x += s;
|
||||
y += s;
|
||||
z += s;
|
||||
w += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator+=(const vec4& v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
w += v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator-=(float s)
|
||||
{
|
||||
x -= s;
|
||||
y -= s;
|
||||
z -= s;
|
||||
w -= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator-=(const vec4& v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
w -= v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator*=(float s)
|
||||
{
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
w *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator*=(const vec4& v)
|
||||
{
|
||||
x *= v.x;
|
||||
y *= v.y;
|
||||
z *= v.z;
|
||||
w *= v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator/=(float s)
|
||||
{
|
||||
x /= s;
|
||||
y /= s;
|
||||
z /= s;
|
||||
w /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4& vec4::operator/=(const vec4& v)
|
||||
{
|
||||
x /= v.x;
|
||||
y /= v.y;
|
||||
z /= v.z;
|
||||
w /= v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 vec4::operator-() const
|
||||
{
|
||||
return vec4(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator+(const vec4& v, float s)
|
||||
{
|
||||
return vec4(v.x + s, v.y + s, v.z + s, v.w + s);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator+(float s, const vec4& v)
|
||||
{
|
||||
return vec4(v.x + s, v.y + s, v.z + s, v.w + s);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator+(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return vec4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator-(const vec4& v, float s)
|
||||
{
|
||||
return vec4(v.x - s, v.y - s, v.z - s, v.w - s);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator-(float s, const vec4& v)
|
||||
{
|
||||
return vec4(s - v.x, s - v.y, s - v.z, s - v.w);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator-(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return vec4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator*(const vec4& v, float s)
|
||||
{
|
||||
return vec4(v.x * s, v.y * s, v.z * s, v.w * s);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator*(float s, const vec4& v)
|
||||
{
|
||||
return vec4(v.x * s, v.y * s, v.z * s, v.w * s);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator*(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return vec4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator/(const vec4& v, float s)
|
||||
{
|
||||
return vec4(v.x / s, v.y / s, v.z / s, v.w / s);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator/(float s, const vec4& v)
|
||||
{
|
||||
return vec4(s / v.x, s / v.y, s / v.z, s / v.w);
|
||||
}
|
||||
|
||||
VEC4_DECL vec4 operator/(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return vec4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
|
||||
}
|
||||
|
||||
VEC4_DECL bool operator==(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z) && (v1.w == v2.w);
|
||||
}
|
||||
|
||||
VEC4_DECL bool operator!=(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z) || (v1.w != v2.w);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_VEC4IMPL_H_ */
|
||||
@@ -0,0 +1,868 @@
|
||||
#ifndef INCLUDE_KYTY_MATH_VECTORANDMATRIX_H_
|
||||
#define INCLUDE_KYTY_MATH_VECTORANDMATRIX_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include <cmath> // IWYU pragma: export
|
||||
|
||||
namespace Kyty::Math::m {
|
||||
|
||||
class vec3;
|
||||
class vec4;
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
class vec2 final
|
||||
{
|
||||
public:
|
||||
vec2() noexcept = default;
|
||||
~vec2() = default;
|
||||
vec2(const vec2& v) noexcept = default;
|
||||
vec2(vec2&& v) noexcept = default;
|
||||
explicit vec2(const vec3& v) noexcept;
|
||||
explicit vec2(const vec4& v) noexcept;
|
||||
explicit vec2(float s) noexcept;
|
||||
explicit vec2(float s1, float s2) noexcept;
|
||||
|
||||
float& operator[](int i);
|
||||
float const& operator[](int i) const;
|
||||
|
||||
vec2& operator=(const vec2& v) = default;
|
||||
vec2& operator=(vec2&& v) noexcept = default;
|
||||
|
||||
vec2& operator+=(float s);
|
||||
vec2& operator+=(const vec2& v);
|
||||
vec2& operator-=(float s);
|
||||
vec2& operator-=(const vec2& v);
|
||||
vec2& operator*=(float s);
|
||||
vec2& operator*=(const vec2& v);
|
||||
vec2& operator/=(float s);
|
||||
vec2& operator/=(const vec2& v);
|
||||
|
||||
vec2 operator-() const;
|
||||
|
||||
friend vec2 operator+(const vec2& v, float s);
|
||||
friend vec2 operator+(float s, const vec2& v);
|
||||
friend vec2 operator+(const vec2& v1, const vec2& v2);
|
||||
friend vec2 operator-(const vec2& v, float s);
|
||||
friend vec2 operator-(float s, const vec2& v);
|
||||
friend vec2 operator-(const vec2& v1, const vec2& v2);
|
||||
friend vec2 operator*(const vec2& v, float s);
|
||||
friend vec2 operator*(float s, const vec2& v);
|
||||
friend vec2 operator*(const vec2& v1, const vec2& v2);
|
||||
friend vec2 operator/(const vec2& v, float s);
|
||||
friend vec2 operator/(float s, const vec2& v);
|
||||
friend vec2 operator/(const vec2& v1, const vec2& v2);
|
||||
|
||||
friend bool operator==(const vec2& v1, const vec2& v2);
|
||||
friend bool operator!=(const vec2& v1, const vec2& v2);
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
float x, r;
|
||||
};
|
||||
union
|
||||
{
|
||||
float y, g;
|
||||
};
|
||||
};
|
||||
|
||||
float data[2];
|
||||
};
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
class vec3 final
|
||||
{
|
||||
public:
|
||||
vec3() noexcept = default;
|
||||
vec3(const vec3& v) noexcept = default;
|
||||
vec3(vec3&& v) noexcept = default;
|
||||
~vec3() = default;
|
||||
explicit vec3(const vec4& v) noexcept;
|
||||
explicit vec3(float s) noexcept;
|
||||
explicit vec3(float s1, float s2, float s3) noexcept;
|
||||
explicit vec3(const vec2& v, float s3) noexcept;
|
||||
|
||||
float& operator[](int i);
|
||||
float const& operator[](int i) const;
|
||||
|
||||
[[nodiscard]] vec2 Xy() const { return vec2(x, y); }
|
||||
[[nodiscard]] vec2 Rg() const { return vec2(r, g); }
|
||||
|
||||
vec3& operator=(const vec3& v) = default;
|
||||
vec3& operator=(vec3&& v) noexcept = default;
|
||||
|
||||
vec3& operator+=(float s);
|
||||
vec3& operator+=(const vec3& v);
|
||||
vec3& operator-=(float s);
|
||||
vec3& operator-=(const vec3& v);
|
||||
vec3& operator*=(float s);
|
||||
vec3& operator*=(const vec3& v);
|
||||
vec3& operator/=(float s);
|
||||
vec3& operator/=(const vec3& v);
|
||||
|
||||
vec3 operator-() const;
|
||||
|
||||
friend vec3 operator+(const vec3& v, float s);
|
||||
friend vec3 operator+(float s, const vec3& v);
|
||||
friend vec3 operator+(const vec3& v1, const vec3& v2);
|
||||
friend vec3 operator-(const vec3& v, float s);
|
||||
friend vec3 operator-(float s, const vec3& v);
|
||||
friend vec3 operator-(const vec3& v1, const vec3& v2);
|
||||
friend vec3 operator*(const vec3& v, float s);
|
||||
friend vec3 operator*(float s, const vec3& v);
|
||||
friend vec3 operator*(const vec3& v1, const vec3& v2);
|
||||
friend vec3 operator/(const vec3& v, float s);
|
||||
friend vec3 operator/(float s, const vec3& v);
|
||||
friend vec3 operator/(const vec3& v1, const vec3& v2);
|
||||
|
||||
friend bool operator==(const vec3& v1, const vec3& v2);
|
||||
friend bool operator!=(const vec3& v1, const vec3& v2);
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
float x, r;
|
||||
};
|
||||
union
|
||||
{
|
||||
float y, g;
|
||||
};
|
||||
union
|
||||
{
|
||||
float z, b;
|
||||
};
|
||||
};
|
||||
|
||||
float data[3];
|
||||
};
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
class vec4 final
|
||||
{
|
||||
public:
|
||||
vec4() noexcept = default;
|
||||
vec4(const vec4& v) noexcept = default;
|
||||
vec4(vec4&& v) noexcept = default;
|
||||
~vec4() = default;
|
||||
explicit vec4(float s) noexcept;
|
||||
explicit vec4(float s1, float s2, float s3, float s4) noexcept;
|
||||
explicit vec4(const vec3& v, float s4) noexcept;
|
||||
|
||||
float& operator[](int i);
|
||||
float const& operator[](int i) const;
|
||||
|
||||
[[nodiscard]] vec2 Xy() const { return vec2(x, y); }
|
||||
[[nodiscard]] vec2 Rg() const { return vec2(r, g); }
|
||||
[[nodiscard]] vec3 Xyz() const { return vec3(x, y, z); }
|
||||
[[nodiscard]] vec3 Rgb() const { return vec3(r, g, b); }
|
||||
|
||||
vec4& operator=(const vec4& v) = default;
|
||||
vec4& operator=(vec4&& v) noexcept = default;
|
||||
|
||||
vec4& operator+=(float s);
|
||||
vec4& operator+=(const vec4& v);
|
||||
vec4& operator-=(float s);
|
||||
vec4& operator-=(const vec4& v);
|
||||
vec4& operator*=(float s);
|
||||
vec4& operator*=(const vec4& v);
|
||||
vec4& operator/=(float s);
|
||||
vec4& operator/=(const vec4& v);
|
||||
|
||||
vec4 operator-() const;
|
||||
|
||||
friend vec4 operator+(const vec4& v, float s);
|
||||
friend vec4 operator+(float s, const vec4& v);
|
||||
friend vec4 operator+(const vec4& v1, const vec4& v2);
|
||||
friend vec4 operator-(const vec4& v, float s);
|
||||
friend vec4 operator-(float s, const vec4& v);
|
||||
friend vec4 operator-(const vec4& v1, const vec4& v2);
|
||||
friend vec4 operator*(const vec4& v, float s);
|
||||
friend vec4 operator*(float s, const vec4& v);
|
||||
friend vec4 operator*(const vec4& v1, const vec4& v2);
|
||||
friend vec4 operator/(const vec4& v, float s);
|
||||
friend vec4 operator/(float s, const vec4& v);
|
||||
friend vec4 operator/(const vec4& v1, const vec4& v2);
|
||||
|
||||
friend bool operator==(const vec4& v1, const vec4& v2);
|
||||
friend bool operator!=(const vec4& v1, const vec4& v2);
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
float x;
|
||||
float r;
|
||||
};
|
||||
union
|
||||
{
|
||||
float y, g;
|
||||
};
|
||||
union
|
||||
{
|
||||
float z, b;
|
||||
};
|
||||
union
|
||||
{
|
||||
float w, a;
|
||||
};
|
||||
};
|
||||
|
||||
float data[4];
|
||||
};
|
||||
};
|
||||
|
||||
class mat3;
|
||||
class mat4;
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
class mat2 final
|
||||
{
|
||||
public:
|
||||
mat2() noexcept = default;
|
||||
mat2(const mat2& m) noexcept = default;
|
||||
mat2(mat2&& m) noexcept = default;
|
||||
~mat2() = default;
|
||||
explicit mat2(const mat3& m) noexcept;
|
||||
explicit mat2(const mat4& m) noexcept;
|
||||
explicit mat2(float x) noexcept;
|
||||
explicit mat2(float x1, float y1, float x2, float y2) noexcept;
|
||||
explicit mat2(const vec2& v1, const vec2& v2) noexcept;
|
||||
|
||||
vec2& operator[](int i);
|
||||
const vec2& operator[](int i) const;
|
||||
|
||||
mat2& operator=(const mat2& m) = default;
|
||||
mat2& operator=(mat2&& m) noexcept = default;
|
||||
|
||||
mat2& operator+=(float s);
|
||||
mat2& operator+=(const mat2& m);
|
||||
mat2& operator-=(float s);
|
||||
mat2& operator-=(const mat2& m);
|
||||
mat2& operator*=(float s);
|
||||
mat2& operator*=(const mat2& m);
|
||||
mat2& operator/=(float s);
|
||||
|
||||
friend mat2 operator+(const mat2& m, float s);
|
||||
friend mat2 operator+(float s, const mat2& m);
|
||||
friend mat2 operator+(const mat2& m1, const mat2& m2);
|
||||
friend mat2 operator-(const mat2& m, float s);
|
||||
friend mat2 operator-(float s, const mat2& m);
|
||||
friend mat2 operator-(const mat2& m1, const mat2& m2);
|
||||
friend mat2 operator*(const mat2& m, float s);
|
||||
friend mat2 operator*(float s, const mat2& m);
|
||||
friend mat2 operator*(const mat2& m1, const mat2& m2);
|
||||
friend vec2 operator*(const mat2& m, const vec2& v);
|
||||
friend vec2 operator*(const vec2& v, const mat2& m);
|
||||
friend mat2 operator/(const mat2& m, float s);
|
||||
friend mat2 operator/(float s, const mat2& m);
|
||||
|
||||
friend bool operator==(const mat2& m1, const mat2& m2);
|
||||
friend bool operator!=(const mat2& m1, const mat2& m2);
|
||||
|
||||
vec2 data[2];
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
class mat3 final
|
||||
{
|
||||
public:
|
||||
mat3() noexcept = default;
|
||||
~mat3() = default;
|
||||
mat3(const mat3& m) noexcept = default;
|
||||
mat3(mat3&& m) noexcept = default;
|
||||
explicit mat3(const mat4& m) noexcept;
|
||||
explicit mat3(float x) noexcept;
|
||||
explicit mat3(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3) noexcept;
|
||||
explicit mat3(const vec3& v1, const vec3& v2, const vec3& v3) noexcept;
|
||||
|
||||
vec3& operator[](int i);
|
||||
const vec3& operator[](int i) const;
|
||||
|
||||
mat3& operator=(const mat3& m) = default;
|
||||
mat3& operator=(mat3&& m) noexcept = default;
|
||||
|
||||
mat3& operator+=(float s);
|
||||
mat3& operator+=(const mat3& m);
|
||||
mat3& operator-=(float s);
|
||||
mat3& operator-=(const mat3& m);
|
||||
mat3& operator*=(float s);
|
||||
mat3& operator*=(const mat3& m);
|
||||
mat3& operator/=(float s);
|
||||
|
||||
friend mat3 operator+(const mat3& m, float s);
|
||||
friend mat3 operator+(float s, const mat3& m);
|
||||
friend mat3 operator+(const mat3& m1, const mat3& m2);
|
||||
friend mat3 operator-(const mat3& m, float s);
|
||||
friend mat3 operator-(float s, const mat3& m);
|
||||
friend mat3 operator-(const mat3& m1, const mat3& m2);
|
||||
friend mat3 operator*(const mat3& m, float s);
|
||||
friend mat3 operator*(float s, const mat3& m);
|
||||
friend mat3 operator*(const mat3& m1, const mat3& m2);
|
||||
friend vec3 operator*(const mat3& m, const vec3& v);
|
||||
friend vec3 operator*(const vec3& v, const mat3& m);
|
||||
friend mat3 operator/(const mat3& m, float s);
|
||||
friend mat3 operator/(float s, const mat3& m);
|
||||
|
||||
friend bool operator==(const mat3& m1, const mat3& m2);
|
||||
friend bool operator!=(const mat3& m1, const mat3& m2);
|
||||
|
||||
vec3 data[3];
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
class mat4 final
|
||||
{
|
||||
public:
|
||||
mat4() noexcept = default;
|
||||
~mat4() = default;
|
||||
mat4(const mat4& m) noexcept = default;
|
||||
mat4(mat4&& m) noexcept = default;
|
||||
explicit mat4(float x) noexcept;
|
||||
explicit mat4(float x1, float y1, float z1, float w1, float x2, float y2, float z2, float w2, float x3, float y3, float z3, float w3,
|
||||
float x4, float y4, float z4, float w4) noexcept;
|
||||
explicit mat4(const vec4& v1, const vec4& v2, const vec4& v3, const vec4& v4) noexcept;
|
||||
|
||||
vec4& operator[](int i);
|
||||
const vec4& operator[](int i) const;
|
||||
|
||||
mat4& operator=(const mat4& m) = default;
|
||||
mat4& operator=(mat4&& m) noexcept = default;
|
||||
|
||||
mat4& operator+=(float s);
|
||||
mat4& operator+=(const mat4& m);
|
||||
mat4& operator-=(float s);
|
||||
mat4& operator-=(const mat4& m);
|
||||
mat4& operator*=(float s);
|
||||
mat4& operator*=(const mat4& m);
|
||||
mat4& operator/=(float s);
|
||||
|
||||
friend mat4 operator+(const mat4& m, float s);
|
||||
friend mat4 operator+(float s, const mat4& m);
|
||||
friend mat4 operator+(const mat4& m1, const mat4& m2);
|
||||
friend mat4 operator-(const mat4& m, float s);
|
||||
friend mat4 operator-(float s, const mat4& m);
|
||||
friend mat4 operator-(const mat4& m1, const mat4& m2);
|
||||
friend mat4 operator*(const mat4& m, float s);
|
||||
friend mat4 operator*(float s, const mat4& m);
|
||||
friend mat4 operator*(const mat4& m1, const mat4& m2);
|
||||
friend vec4 operator*(const mat4& m, const vec4& v);
|
||||
friend vec4 operator*(const vec4& v, const mat4& m);
|
||||
friend mat4 operator/(const mat4& m, float s);
|
||||
friend mat4 operator/(float s, const mat4& m);
|
||||
|
||||
friend bool operator==(const mat4& m1, const mat4& m2);
|
||||
friend bool operator!=(const mat4& m1, const mat4& m2);
|
||||
|
||||
vec4 data[4];
|
||||
};
|
||||
|
||||
inline float* value_ptr(vec2& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
return &v.x;
|
||||
}
|
||||
inline float* value_ptr(vec3& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
return &v.x;
|
||||
}
|
||||
inline float* value_ptr(vec4& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
return &v.x;
|
||||
}
|
||||
inline float* value_ptr(mat2& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
return &v.data[0].x;
|
||||
}
|
||||
inline float* value_ptr(mat3& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
return &v.data[0].x;
|
||||
}
|
||||
inline float* value_ptr(mat4& v) // NOLINT(google-runtime-references)
|
||||
{
|
||||
return &v.data[0].x;
|
||||
}
|
||||
|
||||
inline const float* value_ptr(const vec2& v)
|
||||
{
|
||||
return &v.x;
|
||||
}
|
||||
inline const float* value_ptr(const vec3& v)
|
||||
{
|
||||
return &v.x;
|
||||
}
|
||||
inline const float* value_ptr(const vec4& v)
|
||||
{
|
||||
return &v.x;
|
||||
}
|
||||
inline const float* value_ptr(const mat2& v)
|
||||
{
|
||||
return &v.data[0].x;
|
||||
}
|
||||
inline const float* value_ptr(const mat3& v)
|
||||
{
|
||||
return &v.data[0].x;
|
||||
}
|
||||
inline const float* value_ptr(const mat4& v)
|
||||
{
|
||||
return &v.data[0].x;
|
||||
}
|
||||
|
||||
inline float round(float n)
|
||||
{
|
||||
if (n < 0.0f)
|
||||
{
|
||||
return ceilf(n - 0.5f);
|
||||
}
|
||||
return floorf(n + 0.5f);
|
||||
}
|
||||
|
||||
inline vec2 round(const vec2& v)
|
||||
{
|
||||
return vec2(round(v.x), round(v.y));
|
||||
}
|
||||
inline vec3 round(const vec3& v)
|
||||
{
|
||||
return vec3(round(v.x), round(v.y), round(v.z));
|
||||
}
|
||||
inline vec4 round(const vec4& v)
|
||||
{
|
||||
return vec4(round(v.x), round(v.y), round(v.z), round(v.w));
|
||||
}
|
||||
|
||||
inline float abs(float n)
|
||||
{
|
||||
return fabsf(n);
|
||||
}
|
||||
inline vec2 abs(const vec2& v)
|
||||
{
|
||||
return vec2(abs(v.x), abs(v.y));
|
||||
}
|
||||
inline vec3 abs(const vec3& v)
|
||||
{
|
||||
return vec3(abs(v.x), abs(v.y), abs(v.z));
|
||||
}
|
||||
inline vec4 abs(const vec4& v)
|
||||
{
|
||||
return vec4(abs(v.x), abs(v.y), abs(v.z), abs(v.w));
|
||||
}
|
||||
|
||||
inline vec2 normalize(const vec2& v)
|
||||
{
|
||||
return v / sqrtf(v.x * v.x + v.y * v.y);
|
||||
}
|
||||
inline vec3 normalize(const vec3& v)
|
||||
{
|
||||
return v / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
}
|
||||
inline vec4 normalize(const vec4& v)
|
||||
{
|
||||
return v / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
|
||||
}
|
||||
|
||||
inline float dot(const vec2& v1, const vec2& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y;
|
||||
}
|
||||
inline float dot(const vec3& v1, const vec3& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
inline float dot(const vec4& v1, const vec4& v2)
|
||||
{
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
|
||||
}
|
||||
|
||||
inline vec3 cross(const vec3& x, const vec3& y)
|
||||
{
|
||||
return vec3(x.y * y.z - y.y * x.z, x.z * y.x - y.z * x.x, x.x * y.y - y.x * x.y);
|
||||
}
|
||||
|
||||
inline mat4 rotate(float a, const vec3& v)
|
||||
{
|
||||
float c = cosf(a);
|
||||
float s = sinf(a);
|
||||
float t = 1.0f - c;
|
||||
vec3 u = normalize(v);
|
||||
float tx = t * u.x;
|
||||
float ty = t * u.y;
|
||||
float tz = t * u.z;
|
||||
float sx = s * u.x;
|
||||
float sy = s * u.y;
|
||||
float sz = s * u.z;
|
||||
|
||||
float m1 = c + u.x * tx;
|
||||
float m2 = u.y * tx - sz;
|
||||
float m3 = u.z * tx + sy;
|
||||
float m4 = u.y * tx + sz;
|
||||
float m5 = c + u.y * ty;
|
||||
float m6 = u.y * tz - sx;
|
||||
float m7 = u.z * tx - sy;
|
||||
float m8 = u.z * ty + sx;
|
||||
float m9 = c + u.z * tz;
|
||||
|
||||
return mat4(m1, m4, m7, 0, m2, m5, m8, 0, m3, m6, m9, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
inline mat4 lookAt(const vec3& eye, const vec3& center, const vec3& up)
|
||||
{
|
||||
vec3 f(normalize(center - eye));
|
||||
vec3 s(normalize(cross(f, up)));
|
||||
vec3 u(cross(s, f));
|
||||
|
||||
mat4 r {};
|
||||
|
||||
r.data[0].x = s.x;
|
||||
r.data[0].y = u.x;
|
||||
r.data[0].z = -f.x;
|
||||
r.data[0].w = 0.0f;
|
||||
|
||||
r.data[1].x = s.y;
|
||||
r.data[1].y = u.y;
|
||||
r.data[1].z = -f.y;
|
||||
r.data[1].w = 0.0f;
|
||||
|
||||
r.data[2].x = s.z;
|
||||
r.data[2].y = u.z;
|
||||
r.data[2].z = -f.z;
|
||||
r.data[2].w = 0.0f;
|
||||
|
||||
r.data[3].x = -dot(s, eye);
|
||||
r.data[3].y = -dot(u, eye);
|
||||
r.data[3].z = dot(f, eye);
|
||||
r.data[3].w = 1.0f;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline mat4 perspective(float fovy, float aspect, float z_near, float z_far)
|
||||
{
|
||||
float t = tanf(fovy / 2.0f);
|
||||
|
||||
mat4 r {};
|
||||
|
||||
r.data[0].x = 1.0f / (aspect * t);
|
||||
r.data[0].y = 0.0f;
|
||||
r.data[0].z = 0.0f;
|
||||
r.data[0].w = 0.0f;
|
||||
|
||||
r.data[1].x = 0.0f;
|
||||
r.data[1].y = 1.0f / (t);
|
||||
r.data[1].z = 0.0f;
|
||||
r.data[1].w = 0.0f;
|
||||
|
||||
r.data[2].x = 0.0f;
|
||||
r.data[2].y = 0.0f;
|
||||
r.data[2].z = -(z_far + z_near) / (z_far - z_near);
|
||||
r.data[2].w = -1.0f;
|
||||
|
||||
r.data[3].x = 0.0f;
|
||||
r.data[3].y = 0.0f;
|
||||
r.data[3].z = -(2.0f * z_far * z_near) / (z_far - z_near);
|
||||
r.data[3].w = 0.0f;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline mat4 ortho(float left, float right, float bottom, float top, float z_near, float z_far)
|
||||
{
|
||||
mat4 r {};
|
||||
|
||||
r.data[0].x = 2.0f / (right - left);
|
||||
r.data[0].y = 0.0f;
|
||||
r.data[0].z = 0.0f;
|
||||
r.data[0].w = 0.0f;
|
||||
|
||||
r.data[1].x = 0.0f;
|
||||
r.data[1].y = 2.0f / (top - bottom);
|
||||
r.data[1].z = 0.0f;
|
||||
r.data[1].w = 0.0f;
|
||||
|
||||
r.data[2].x = 0.0f;
|
||||
r.data[2].y = 0.0f;
|
||||
r.data[2].z = -2.0f / (z_far - z_near);
|
||||
r.data[2].w = 0.0f;
|
||||
|
||||
r.data[3].x = -(right + left) / (right - left);
|
||||
r.data[3].y = -(top + bottom) / (top - bottom);
|
||||
r.data[3].z = -(z_far + z_near) / (z_far - z_near);
|
||||
r.data[3].w = 1.0f;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline float determinant(const mat2& m)
|
||||
{
|
||||
return m.data[0].x * m.data[1].y - m.data[0].y * m.data[1].x;
|
||||
}
|
||||
|
||||
inline float determinant(const mat3& m)
|
||||
{
|
||||
return m.data[0].x * determinant(mat2(m.data[1].y, m.data[1].z, m.data[2].y, m.data[2].z)) -
|
||||
m.data[0].y * determinant(mat2(m.data[1].x, m.data[1].z, m.data[2].x, m.data[2].z)) +
|
||||
m.data[0].z * determinant(mat2(m.data[1].x, m.data[1].y, m.data[2].x, m.data[2].y));
|
||||
}
|
||||
|
||||
inline float determinant(const mat4& m)
|
||||
{
|
||||
return m.data[0].x * determinant(mat3(m.data[1].y, m.data[1].z, m.data[1].w, m.data[2].y, m.data[2].z, m.data[2].w, m.data[3].y,
|
||||
m.data[3].z, m.data[3].w)) -
|
||||
m.data[0].y * determinant(mat3(m.data[1].x, m.data[1].z, m.data[1].w, m.data[2].x, m.data[2].z, m.data[2].w, m.data[3].x,
|
||||
m.data[3].z, m.data[3].w)) +
|
||||
m.data[0].z * determinant(mat3(m.data[1].x, m.data[1].y, m.data[1].w, m.data[2].x, m.data[2].y, m.data[2].w, m.data[3].x,
|
||||
m.data[3].y, m.data[3].w)) -
|
||||
m.data[0].w * determinant(mat3(m.data[1].x, m.data[1].y, m.data[1].z, m.data[2].x, m.data[2].y, m.data[2].z, m.data[3].x,
|
||||
m.data[3].y, m.data[3].z));
|
||||
}
|
||||
|
||||
inline mat2 inverseTranspose(const mat2& m)
|
||||
{
|
||||
float x1 = m.data[1].y;
|
||||
float y1 = m.data[1].x;
|
||||
float x2 = m.data[0].y;
|
||||
float y2 = m.data[0].x;
|
||||
|
||||
return mat2(x1, -y1, -x2, y2) / determinant(m);
|
||||
}
|
||||
|
||||
inline mat3 inverseTranspose(const mat3& m)
|
||||
{
|
||||
float x1 = determinant(mat2(m.data[1].y, m.data[1].z, m.data[2].y, m.data[2].z));
|
||||
|
||||
float y1 = determinant(mat2(m.data[1].x, m.data[1].z, m.data[2].x, m.data[2].z));
|
||||
|
||||
float z1 = determinant(mat2(m.data[1].x, m.data[1].y, m.data[2].x, m.data[2].y));
|
||||
|
||||
float x2 = determinant(mat2(m.data[0].y, m.data[0].z, m.data[2].y, m.data[2].z));
|
||||
|
||||
float y2 = determinant(mat2(m.data[0].x, m.data[0].z, m.data[2].x, m.data[2].z));
|
||||
|
||||
float z2 = determinant(mat2(m.data[0].x, m.data[0].y, m.data[2].x, m.data[2].y));
|
||||
|
||||
float x3 = determinant(mat2(m.data[0].y, m.data[0].z, m.data[1].y, m.data[1].z));
|
||||
|
||||
float y3 = determinant(mat2(m.data[0].x, m.data[0].z, m.data[1].x, m.data[1].z));
|
||||
|
||||
float z3 = determinant(mat2(m.data[0].x, m.data[0].y, m.data[1].x, m.data[1].y));
|
||||
|
||||
return mat3(x1, -y1, z1, -x2, y2, -z2, x3, -y3, z3) / determinant(m);
|
||||
}
|
||||
|
||||
inline mat4 inverseTranspose(const mat4& m)
|
||||
{
|
||||
float x1 = determinant(
|
||||
mat3(m.data[1].y, m.data[1].z, m.data[1].w, m.data[2].y, m.data[2].z, m.data[2].w, m.data[3].y, m.data[3].z, m.data[3].w));
|
||||
|
||||
float y1 = determinant(
|
||||
mat3(m.data[1].x, m.data[1].z, m.data[1].w, m.data[2].x, m.data[2].z, m.data[2].w, m.data[3].x, m.data[3].z, m.data[3].w));
|
||||
|
||||
float z1 = determinant(
|
||||
mat3(m.data[1].x, m.data[1].y, m.data[1].w, m.data[2].x, m.data[2].y, m.data[2].w, m.data[3].x, m.data[3].y, m.data[3].w));
|
||||
|
||||
float w1 = determinant(
|
||||
mat3(m.data[1].x, m.data[1].y, m.data[1].z, m.data[2].x, m.data[2].y, m.data[2].z, m.data[3].x, m.data[3].y, m.data[3].z));
|
||||
|
||||
float x2 = determinant(
|
||||
mat3(m.data[0].y, m.data[0].z, m.data[0].w, m.data[2].y, m.data[2].z, m.data[2].w, m.data[3].y, m.data[3].z, m.data[3].w));
|
||||
|
||||
float y2 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].z, m.data[0].w, m.data[2].x, m.data[2].z, m.data[2].w, m.data[3].x, m.data[3].z, m.data[3].w));
|
||||
|
||||
float z2 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].y, m.data[0].w, m.data[2].x, m.data[2].y, m.data[2].w, m.data[3].x, m.data[3].y, m.data[3].w));
|
||||
|
||||
float w2 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].y, m.data[0].z, m.data[2].x, m.data[2].y, m.data[2].z, m.data[3].x, m.data[3].y, m.data[3].z));
|
||||
|
||||
float x3 = determinant(
|
||||
mat3(m.data[0].y, m.data[0].z, m.data[0].w, m.data[1].y, m.data[1].z, m.data[1].w, m.data[3].y, m.data[3].z, m.data[3].w));
|
||||
|
||||
float y3 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].z, m.data[0].w, m.data[1].x, m.data[1].z, m.data[1].w, m.data[3].x, m.data[3].z, m.data[3].w));
|
||||
|
||||
float z3 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].y, m.data[0].w, m.data[1].x, m.data[1].y, m.data[1].w, m.data[3].x, m.data[3].y, m.data[3].w));
|
||||
|
||||
float w3 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].y, m.data[0].z, m.data[1].x, m.data[1].y, m.data[1].z, m.data[3].x, m.data[3].y, m.data[3].z));
|
||||
|
||||
float x4 = determinant(
|
||||
mat3(m.data[0].y, m.data[0].z, m.data[0].w, m.data[1].y, m.data[1].z, m.data[1].w, m.data[2].y, m.data[2].z, m.data[2].w));
|
||||
|
||||
float y4 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].z, m.data[0].w, m.data[1].x, m.data[1].z, m.data[1].w, m.data[2].x, m.data[2].z, m.data[2].w));
|
||||
|
||||
float z4 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].y, m.data[0].w, m.data[1].x, m.data[1].y, m.data[1].w, m.data[2].x, m.data[2].y, m.data[2].w));
|
||||
|
||||
float w4 = determinant(
|
||||
mat3(m.data[0].x, m.data[0].y, m.data[0].z, m.data[1].x, m.data[1].y, m.data[1].z, m.data[2].x, m.data[2].y, m.data[2].z));
|
||||
|
||||
return mat4(x1, -y1, z1, -w1, -x2, y2, -z2, w2, x3, -y3, z3, -w3, -x4, y4, -z4, w4) / determinant(m);
|
||||
}
|
||||
|
||||
inline mat2 transpose(const mat2& m)
|
||||
{
|
||||
return mat2(m.data[0].x, m.data[1].x, m.data[0].y, m.data[1].y);
|
||||
}
|
||||
|
||||
inline mat3 transpose(const mat3& m)
|
||||
{
|
||||
return mat3(m.data[0].x, m.data[1].x, m.data[2].x, m.data[0].y, m.data[1].y, m.data[2].y, m.data[0].z, m.data[1].z, m.data[2].z);
|
||||
}
|
||||
|
||||
inline mat4 transpose(const mat4& m)
|
||||
{
|
||||
return mat4(m.data[0].x, m.data[1].x, m.data[2].x, m.data[3].x, m.data[0].y, m.data[1].y, m.data[2].y, m.data[3].y, m.data[0].z,
|
||||
m.data[1].z, m.data[2].z, m.data[3].z, m.data[0].w, m.data[1].w, m.data[2].w, m.data[3].w);
|
||||
}
|
||||
|
||||
inline mat2 inverse(const mat2& m)
|
||||
{
|
||||
return transpose(inverseTranspose(m));
|
||||
}
|
||||
|
||||
inline mat3 inverse(const mat3& m)
|
||||
{
|
||||
return transpose(inverseTranspose(m));
|
||||
}
|
||||
|
||||
inline mat4 inverse(const mat4& m)
|
||||
{
|
||||
return transpose(inverseTranspose(m));
|
||||
}
|
||||
|
||||
inline mat2 make_mat2(const float* m)
|
||||
{
|
||||
return mat2(m[0], m[1], m[2], m[3]);
|
||||
}
|
||||
|
||||
inline mat3 make_mat3(const float* m)
|
||||
{
|
||||
return mat3(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
|
||||
}
|
||||
|
||||
inline mat4 make_mat4(const float* m)
|
||||
{
|
||||
return mat4(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]);
|
||||
}
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline float max(float a, float b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
inline vec2 max(const vec2& a, const vec2& b)
|
||||
{
|
||||
return vec2(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y);
|
||||
}
|
||||
inline vec3 max(const vec3& a, const vec3& b)
|
||||
{
|
||||
return vec3(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z);
|
||||
}
|
||||
inline vec4 max(const vec4& a, const vec4& b)
|
||||
{
|
||||
return vec4(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z, a.w > b.w ? a.w : b.w);
|
||||
}
|
||||
inline vec2 max(const vec2& a, float b)
|
||||
{
|
||||
return max(a, vec2(b));
|
||||
}
|
||||
inline vec3 max(const vec3& a, float b)
|
||||
{
|
||||
return max(a, vec3(b));
|
||||
}
|
||||
inline vec4 max(const vec4& a, float b)
|
||||
{
|
||||
return max(a, vec4(b));
|
||||
}
|
||||
|
||||
inline float min(float a, float b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
inline vec2 min(const vec2& a, const vec2& b)
|
||||
{
|
||||
return vec2(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y);
|
||||
}
|
||||
inline vec3 min(const vec3& a, const vec3& b)
|
||||
{
|
||||
return vec3(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z);
|
||||
}
|
||||
inline vec4 min(const vec4& a, const vec4& b)
|
||||
{
|
||||
return vec4(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z, a.w < b.w ? a.w : b.w);
|
||||
}
|
||||
inline vec2 min(const vec2& a, float b)
|
||||
{
|
||||
return min(a, vec2(b));
|
||||
}
|
||||
inline vec3 min(const vec3& a, float b)
|
||||
{
|
||||
return min(a, vec3(b));
|
||||
}
|
||||
inline vec4 min(const vec4& a, float b)
|
||||
{
|
||||
return min(a, vec4(b));
|
||||
}
|
||||
|
||||
inline float clamp(float x, float min_val, float max_val)
|
||||
{
|
||||
return min(max(x, min_val), max_val);
|
||||
}
|
||||
inline vec2 clamp(const vec2& x, float min_val, float max_val)
|
||||
{
|
||||
return min(max(x, min_val), max_val);
|
||||
}
|
||||
inline vec3 clamp(const vec3& x, float min_val, float max_val)
|
||||
{
|
||||
return min(max(x, min_val), max_val);
|
||||
}
|
||||
inline vec4 clamp(const vec4& x, float min_val, float max_val)
|
||||
{
|
||||
return min(max(x, min_val), max_val);
|
||||
}
|
||||
|
||||
inline float radians(float degrees)
|
||||
{
|
||||
return degrees * (0.01745329251994329576923690768489f);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Math::m
|
||||
|
||||
#define VEC2_DECL inline /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
#define VEC3_DECL inline /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
#define VEC4_DECL inline /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
#define MAT2_DECL inline /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
#define MAT3_DECL inline /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
#define MAT4_DECL inline /*NOLINT(cppcoreguidelines-macro-usage)*/
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include "Kyty/Math/Mat2Impl.h"
|
||||
#include "Kyty/Math/Mat3Impl.h"
|
||||
#include "Kyty/Math/Mat4Impl.h"
|
||||
#include "Kyty/Math/Vec2Impl.h"
|
||||
#include "Kyty/Math/Vec3Impl.h"
|
||||
#include "Kyty/Math/Vec4Impl.h"
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#endif /* INCLUDE_KYTY_MATH_VECTORANDMATRIX_H_ */
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef INCLUDE_KYTY_SCRIPTS_BUILDTOOLS_H_
|
||||
#define INCLUDE_KYTY_SCRIPTS_BUILDTOOLS_H_
|
||||
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
namespace Kyty::BuildTools {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(BuildTools);
|
||||
|
||||
} // namespace Kyty::BuildTools
|
||||
|
||||
#endif /* INCLUDE_KYTY_SCRIPTS_BUILDTOOLS_H_ */
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef INCLUDE_KYTY_SCRIPTS_LUACPP_H_
|
||||
#define INCLUDE_KYTY_SCRIPTS_LUACPP_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
//#define LUA_BUILD_AS_DLL
|
||||
//#define LUA_USE_WINDOWS
|
||||
#else
|
||||
#define LUA_USE_LINUX
|
||||
#endif
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
//
|
||||
#include "lualib.h"
|
||||
//
|
||||
#include "lauxlib.h"
|
||||
//
|
||||
}
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#endif /* INCLUDE_KYTY_SCRIPTS_LUACPP_H_ */
|
||||
@@ -0,0 +1,220 @@
|
||||
#ifndef INCLUDE_KYTY_SCRIPTS_SCRIPTS_H_
|
||||
#define INCLUDE_KYTY_SCRIPTS_SCRIPTS_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||
//#include <string.h>
|
||||
#endif
|
||||
|
||||
#define KYTY_LUA_5_2 1
|
||||
#define KYTY_LUA_5_3 2
|
||||
#define KYTY_LUA_VER KYTY_LUA_5_2
|
||||
|
||||
namespace Kyty::Scripts {
|
||||
|
||||
using LuaState = void;
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Scripts);
|
||||
|
||||
enum class ScriptError
|
||||
{
|
||||
Ok,
|
||||
SyntaxError,
|
||||
FileError,
|
||||
RunError,
|
||||
UnknownError
|
||||
};
|
||||
|
||||
using script_func_t = int (*)(LuaState*);
|
||||
using help_func_t = void (*)();
|
||||
|
||||
#define KYTY_SCRIPT_NAME(name) name([[maybe_unused]] Kyty::Scripts::LuaState* LS)
|
||||
//#define STATIC_SCRIPT_FUNC(name) static int SCRIPT_NAME(name)
|
||||
#define KYTY_SCRIPT_FUNC(name) int KYTY_SCRIPT_NAME(name)
|
||||
|
||||
#define KYTY_STATIC_SCRIPT_FUNC(name) \
|
||||
static int name##_private([[maybe_unused]] Kyty::Scripts::LuaState* LS, [[maybe_unused]] Scripts::ScriptFuncResult* script_result); \
|
||||
static int name(Kyty::Scripts::LuaState* LS) \
|
||||
{ \
|
||||
Scripts::ScriptFuncResult script_result; \
|
||||
int r = name##_private(LS, &script_result); \
|
||||
script_result.ThrowError(); \
|
||||
return r; \
|
||||
} \
|
||||
static int name##_private([[maybe_unused]] Kyty::Scripts::LuaState* LS, [[maybe_unused]] Scripts::ScriptFuncResult* script_result)
|
||||
|
||||
ScriptError RunFile(const String& file_name);
|
||||
ScriptError RunString(const String& source);
|
||||
const String& GetErrMsg();
|
||||
void SetErrMsg(const String& msg);
|
||||
void ResetErrMsg();
|
||||
void PushString(const String& str);
|
||||
void PushDouble(double d);
|
||||
#if KYTY_LUA_VER == KYTY_LUA_5_3
|
||||
void PushInteger(int64_t i);
|
||||
#else
|
||||
void PushInteger(int32_t i);
|
||||
#endif
|
||||
|
||||
void RegisterFunc(const char* name, script_func_t func, help_func_t help);
|
||||
void RegisterSystemFunc(const char* name, script_func_t func);
|
||||
void UnregisterFunc(const char* name);
|
||||
|
||||
int ArgGetVarCount();
|
||||
void ArgDbgDump();
|
||||
|
||||
void PrintHelp();
|
||||
|
||||
class ScriptVar;
|
||||
|
||||
class ScriptPair final
|
||||
{
|
||||
public:
|
||||
ScriptPair(const ScriptVar& key, const ScriptVar& value);
|
||||
~ScriptPair();
|
||||
|
||||
ScriptPair(const ScriptPair& src);
|
||||
|
||||
ScriptPair& operator=(const ScriptPair&) = delete;
|
||||
ScriptPair(ScriptPair&&) noexcept = delete;
|
||||
ScriptPair& operator=(ScriptPair&&) noexcept = delete;
|
||||
|
||||
[[nodiscard]] const ScriptVar& GetKey() const { return *m_key; }
|
||||
|
||||
[[nodiscard]] const ScriptVar& GetValue() const { return *m_value; }
|
||||
|
||||
private:
|
||||
ScriptVar* m_key;
|
||||
ScriptVar* m_value;
|
||||
};
|
||||
|
||||
class ScriptTable final
|
||||
{
|
||||
public:
|
||||
using List = Vector<ScriptPair>;
|
||||
|
||||
void Add(const ScriptVar& k, const ScriptVar& v);
|
||||
|
||||
void DbgPrint(int depth) const;
|
||||
|
||||
#if KYTY_LUA_VER == KYTY_LUA_5_3
|
||||
ScriptVar At(int64_t m_key) const;
|
||||
#endif
|
||||
[[nodiscard]] ScriptVar At(const String& key) const;
|
||||
[[nodiscard]] ScriptVar At(double key) const;
|
||||
|
||||
[[nodiscard]] uint32_t Count() const { return m_pairs.Size(); }
|
||||
[[nodiscard]] ScriptVar GetKey(uint32_t index) const;
|
||||
[[nodiscard]] ScriptVar GetValue(uint32_t index) const;
|
||||
|
||||
[[nodiscard]] const List& GetList() const { return m_pairs; }
|
||||
|
||||
private:
|
||||
List m_pairs;
|
||||
};
|
||||
|
||||
class ScriptFunction final
|
||||
{
|
||||
public:
|
||||
void LoadFromStack();
|
||||
|
||||
[[nodiscard]] String ToDbgString() const;
|
||||
|
||||
private:
|
||||
static int LuaWriter(LuaState* ls, const void* p, size_t sz, void* ud);
|
||||
|
||||
Vector<uint8_t> m_dump;
|
||||
};
|
||||
|
||||
class ScriptVar
|
||||
{
|
||||
public:
|
||||
ScriptVar();
|
||||
|
||||
virtual ~ScriptVar();
|
||||
|
||||
ScriptVar(const ScriptVar& src);
|
||||
ScriptVar(ScriptVar&& src) noexcept;
|
||||
ScriptVar& operator=(const ScriptVar& src);
|
||||
ScriptVar& operator=(ScriptVar&& src) noexcept;
|
||||
|
||||
void DbgPrint(int depth) const;
|
||||
|
||||
static ScriptVar ReadVar(int index, bool with_metatable_index);
|
||||
|
||||
[[nodiscard]] bool IsTable() const;
|
||||
[[nodiscard]] bool IsNil() const;
|
||||
[[nodiscard]] bool IsFunction() const;
|
||||
[[nodiscard]] bool IsCFunction() const;
|
||||
[[nodiscard]] bool IsDouble() const;
|
||||
#if KYTY_LUA_VER == KYTY_LUA_5_3
|
||||
bool IsInteger() const;
|
||||
#else
|
||||
[[nodiscard]] bool IsInteger() const;
|
||||
#endif
|
||||
[[nodiscard]] bool IsString() const;
|
||||
[[nodiscard]] bool IsUserdata() const;
|
||||
|
||||
#if KYTY_LUA_VER == KYTY_LUA_5_3
|
||||
int64_t ToInteger() const;
|
||||
#else
|
||||
[[nodiscard]] int32_t ToInteger() const;
|
||||
#endif
|
||||
[[nodiscard]] double ToDouble() const;
|
||||
[[nodiscard]] float ToFloat() const;
|
||||
[[nodiscard]] bool ToBool() const;
|
||||
[[nodiscard]] String ToString() const;
|
||||
[[nodiscard]] void* ToUserdata() const;
|
||||
[[nodiscard]] const ScriptTable& ToTable() const;
|
||||
[[nodiscard]] const ScriptTable::List& GetPairs() const;
|
||||
|
||||
[[nodiscard]] ScriptVar At(int64_t key) const;
|
||||
[[nodiscard]] ScriptVar At(const String& key) const;
|
||||
[[nodiscard]] ScriptVar At(const char* key) const;
|
||||
[[nodiscard]] ScriptVar At(double key) const;
|
||||
|
||||
[[nodiscard]] uint32_t Count() const;
|
||||
[[nodiscard]] uint32_t Size() const;
|
||||
[[nodiscard]] ScriptVar GetKey(uint32_t index) const;
|
||||
[[nodiscard]] ScriptVar GetValue(uint32_t index) const;
|
||||
|
||||
private:
|
||||
class ScriptVarPrivate;
|
||||
ScriptVarPrivate* m_p = {nullptr};
|
||||
};
|
||||
|
||||
ScriptVar GlobalGetVar(const String& var_name);
|
||||
ScriptVar GlobalGetVarWithParent(const String& var_name);
|
||||
ScriptVar ArgGetVar(int index);
|
||||
ScriptVar ArgGetVarWithParent(int index);
|
||||
|
||||
constexpr size_t SCRIPT_FUNC_ERR_SIZE = 1024;
|
||||
|
||||
class ScriptFuncResult
|
||||
{
|
||||
public:
|
||||
ScriptFuncResult() = default;
|
||||
|
||||
void SetError(const String& msg);
|
||||
|
||||
void ThrowError();
|
||||
|
||||
private:
|
||||
bool m_ok = {true};
|
||||
char m_msg[SCRIPT_FUNC_ERR_SIZE + 1] = {0};
|
||||
};
|
||||
|
||||
#define KYTY_SCRIPT_FUNC_BEGIN() [[maybe_unused]] auto* L = static_cast<struct lua_State*>(LS);
|
||||
#define KYTY_SCRIPT_THROW_ERROR(msg) \
|
||||
{ \
|
||||
script_result->SetError(msg); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
} // namespace Kyty::Scripts
|
||||
|
||||
#endif /* INCLUDE_KYTY_SCRIPTS_SCRIPTS_H_ */
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef INCLUDE_KYTY_SCRIPTS_SCRIPTSLOADER_H_
|
||||
#define INCLUDE_KYTY_SCRIPTS_SCRIPTSLOADER_H_
|
||||
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
namespace Kyty::Scripts {
|
||||
|
||||
void SetLoadError(const String& err);
|
||||
String GetLoadError();
|
||||
void ResetLoadError();
|
||||
bool RunScript(const String& lua_file_name);
|
||||
|
||||
} // namespace Kyty::Scripts
|
||||
|
||||
#endif /* INCLUDE_KYTY_SCRIPTS_SCRIPTSLOADER_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSDBG_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSDBG_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxDbg.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsDbg.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSDBG_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSFILEIO_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSFILEIO_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxFileIO.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsFileIO.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSFILEIO_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSHEAP_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSHEAP_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxHeap.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsHeap.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSHEAP_H_ */
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSDBG_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSDBG_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
struct sys_dbg_stack_info_t
|
||||
{
|
||||
uintptr_t code_addr;
|
||||
uintptr_t addr;
|
||||
uintptr_t commited_addr;
|
||||
size_t commited_size;
|
||||
size_t total_size;
|
||||
size_t code_size;
|
||||
};
|
||||
|
||||
using exception_filter_func_t = void (*)(void* addr);
|
||||
|
||||
void sys_stack_walk(void** stack, int* depth);
|
||||
void sys_stack_usage(sys_dbg_stack_info_t& s);
|
||||
void sys_stack_usage_print(sys_dbg_stack_info_t& stack);
|
||||
void sys_get_code_info(uintptr_t* addr, size_t* size);
|
||||
void sys_set_exception_filter(exception_filter_func_t func);
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSDBG_H_ */
|
||||
@@ -0,0 +1,104 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSFILEIO_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSFILEIO_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Sys/SysLinuxTimer.h"
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
enum sys_file_type_t
|
||||
{
|
||||
SYS_FILE_ERROR,
|
||||
SYS_FILE_MEMORY_STAT,
|
||||
SYS_FILE_FILE,
|
||||
SYS_FILE_MEMORY_DYN
|
||||
};
|
||||
|
||||
enum sys_file_cache_type_t
|
||||
{
|
||||
SYS_FILE_CACHE_AUTO = 0,
|
||||
SYS_FILE_CACHE_RANDOM_ACCESS = 1,
|
||||
SYS_FILE_CACHE_SEQUENTIAL_SCAN = 2
|
||||
};
|
||||
|
||||
struct sys_file_mem_buf_t
|
||||
{
|
||||
uint8_t* base;
|
||||
uint8_t* ptr;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct sys_file_t
|
||||
{
|
||||
sys_file_type_t type;
|
||||
union
|
||||
{
|
||||
FILE* f;
|
||||
sys_file_mem_buf_t* buf;
|
||||
};
|
||||
};
|
||||
|
||||
struct sys_file_find_t
|
||||
{
|
||||
String path_with_name;
|
||||
SysFileTimeStruct last_access_time;
|
||||
SysFileTimeStruct last_write_time;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
struct sys_dir_entry_t
|
||||
{
|
||||
String name;
|
||||
bool is_file;
|
||||
};
|
||||
|
||||
void sys_file_read(void* data, uint32_t size, sys_file_t& f, uint32_t* bytes_read = 0);
|
||||
void sys_file_write(const void* data, uint32_t size, sys_file_t& f, uint32_t* bytes_written = 0);
|
||||
void sys_file_read_r(void* data, uint32_t size, sys_file_t& f);
|
||||
void sys_file_write_r(const void* data, uint32_t size, sys_file_t& f);
|
||||
sys_file_t* sys_file_create(const String& file_name);
|
||||
sys_file_t* sys_file_open_r(const String& file_name, sys_file_cache_type_t cache_type = SYS_FILE_CACHE_AUTO);
|
||||
sys_file_t* sys_file_open_w(const String& file_name, sys_file_cache_type_t cache_type = SYS_FILE_CACHE_AUTO);
|
||||
sys_file_t* sys_file_open(uint8_t* buf, uint32_t buf_size);
|
||||
sys_file_t* sys_file_create();
|
||||
sys_file_t* sys_file_open_rw(const String& file_name, sys_file_cache_type_t cache_type = SYS_FILE_CACHE_AUTO);
|
||||
void sys_file_close(sys_file_t* f);
|
||||
uint64_t sys_file_size(sys_file_t& f);
|
||||
bool sys_file_seek(sys_file_t& f, uint64_t offset);
|
||||
uint64_t sys_file_tell(sys_file_t& f);
|
||||
bool sys_file_truncate(sys_file_t& f, uint64_t size);
|
||||
void sys_file_write(uint32_t n, sys_file_t& f);
|
||||
void sys_file_write_r(uint32_t n, sys_file_t& f);
|
||||
uint64_t sys_file_size(const String& file_name);
|
||||
bool sys_file_is_error(sys_file_t& f);
|
||||
bool sys_file_io_init();
|
||||
bool sys_file_is_directory_existing(const String& path);
|
||||
bool sys_file_is_file_existing(const String& name);
|
||||
bool sys_file_create_directory(const String& path);
|
||||
bool sys_file_delete_directory(const String& path);
|
||||
bool sys_file_delete_file(const String& name);
|
||||
bool sys_file_flush(sys_file_t& f);
|
||||
SysFileTimeStruct sys_file_get_last_access_time_utc(const String& name);
|
||||
SysFileTimeStruct sys_file_get_last_write_time_utc(const String& name);
|
||||
void sys_file_get_last_access_and_write_time_utc(const String& name, SysFileTimeStruct& a, SysFileTimeStruct& w);
|
||||
void sys_file_get_last_access_and_write_time_utc(sys_file_t& f, SysFileTimeStruct& a, SysFileTimeStruct& w);
|
||||
bool sys_file_set_last_access_time_utc(const String& name, SysFileTimeStruct& access);
|
||||
bool sys_file_set_last_write_time_utc(const String& name, SysFileTimeStruct& write);
|
||||
bool sys_file_set_last_access_and_write_time_utc(const String& name, SysFileTimeStruct& access, SysFileTimeStruct& write);
|
||||
void sys_file_find_files(const String& path, Kyty::Vector<sys_file_find_t>& out);
|
||||
void sys_file_get_dents(const String& path, Kyty::Vector<sys_dir_entry_t>& out);
|
||||
bool sys_file_copy_file(const String& src, const String& dst);
|
||||
bool sys_file_move_file(const String& src, const String& dst);
|
||||
void sys_file_remove_readonly(const String& name);
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSFILEIO_H_ */
|
||||
@@ -0,0 +1,98 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSHEAP_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSHEAP_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
#include "Kyty/Sys/SysLinuxSync.h"
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
typedef SysCS* sys_heap_id_t;
|
||||
|
||||
inline sys_heap_id_t sys_heap_create()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline sys_heap_id_t sys_heap_deafult()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void* sys_heap_alloc(sys_heap_id_t heap_id, size_t size)
|
||||
{
|
||||
void* m = malloc(size);
|
||||
|
||||
EXIT_IF(m == 0);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void* sys_heap_realloc(sys_heap_id_t heap_id, void* p, size_t size)
|
||||
{
|
||||
void* m = p ? realloc(p, size) : malloc(size);
|
||||
|
||||
if (m == 0)
|
||||
{
|
||||
EXIT_IF(m == 0);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void sys_heap_free(sys_heap_id_t heap_id, void* p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
inline sys_heap_id_t sys_heap_create_s()
|
||||
{
|
||||
SysCS* cs = new SysCS;
|
||||
cs->Init();
|
||||
return cs;
|
||||
}
|
||||
|
||||
inline void* sys_heap_alloc_s(sys_heap_id_t heap_id, size_t size)
|
||||
{
|
||||
heap_id->Enter();
|
||||
|
||||
void* m = malloc(size);
|
||||
|
||||
heap_id->Leave();
|
||||
|
||||
EXIT_IF(m == 0);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void* sys_heap_realloc_s(sys_heap_id_t heap_id, void* p, size_t size)
|
||||
{
|
||||
heap_id->Enter();
|
||||
|
||||
void* m = p ? realloc(p, size) : malloc(size);
|
||||
|
||||
heap_id->Leave();
|
||||
|
||||
EXIT_IF(m == 0);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void sys_heap_free_s(sys_heap_id_t heap_id, void* p)
|
||||
{
|
||||
heap_id->Enter();
|
||||
|
||||
free(p);
|
||||
|
||||
heap_id->Leave();
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSHEAP_H_ */
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSSTDIO_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSSTDIO_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
inline uint32_t sys_vscprintf(const char* format, va_list argptr)
|
||||
{
|
||||
int len;
|
||||
va_list argcopy;
|
||||
va_copy(argcopy, argptr);
|
||||
len = vsnprintf(0, 0, format, argcopy);
|
||||
va_end(argcopy);
|
||||
return len < 0 ? 0 : len;
|
||||
}
|
||||
|
||||
inline uint32_t sys_vsnprintf(char* Dest, size_t Count, const char* Format, va_list Args)
|
||||
{
|
||||
int len = vsnprintf(Dest, Count + 1, Format, Args);
|
||||
return len < 0 ? 0 : len;
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSSTDIO_H_ */
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSSTDLIB_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSSTDLIB_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
inline float sys_strtof(const char* nptr, char** endptr)
|
||||
{
|
||||
return strtof(nptr, endptr);
|
||||
}
|
||||
|
||||
inline double sys_strtod(const char* nptr, char** endptr)
|
||||
{
|
||||
return strtod(nptr, endptr);
|
||||
}
|
||||
|
||||
inline int32_t sys_strtoi32(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
long r = strtol(nptr, endptr, base);
|
||||
if (r >= static_cast<long>(INT32_MAX))
|
||||
{
|
||||
return INT32_MAX;
|
||||
}
|
||||
if (r <= static_cast<long>(INT32_MIN))
|
||||
{
|
||||
return INT32_MIN;
|
||||
}
|
||||
return static_cast<int32_t>(r);
|
||||
}
|
||||
|
||||
inline uint32_t sys_strtoui32(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
return strtoul(nptr, endptr, base);
|
||||
}
|
||||
|
||||
inline int64_t sys_strtoi64(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
return strtoll(nptr, endptr, base);
|
||||
}
|
||||
|
||||
inline uint64_t sys_strtoui64(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
return strtoull(nptr, endptr, base);
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSSTDLIB_H_ */
|
||||
@@ -0,0 +1,82 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSSYNC_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSSYNC_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
class SysCS
|
||||
{
|
||||
public:
|
||||
SysCS() { check_ptr = 0; }
|
||||
|
||||
void Init()
|
||||
{
|
||||
EXIT_IF(check_ptr != 0);
|
||||
|
||||
check_ptr = this;
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
pthread_mutex_init(&m, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
void Delete()
|
||||
{
|
||||
EXIT_IF(check_ptr != this);
|
||||
|
||||
check_ptr = 0;
|
||||
pthread_mutex_destroy(&m);
|
||||
}
|
||||
|
||||
~SysCS() { EXIT_IF(check_ptr != 0); }
|
||||
|
||||
void Enter()
|
||||
{
|
||||
EXIT_IF(check_ptr != this);
|
||||
|
||||
pthread_mutex_lock(&m);
|
||||
}
|
||||
|
||||
bool TryEnter()
|
||||
{
|
||||
EXIT_IF(check_ptr != this);
|
||||
|
||||
return pthread_mutex_trylock(&m) == 0;
|
||||
}
|
||||
|
||||
void Leave()
|
||||
{
|
||||
EXIT_IF(check_ptr != this);
|
||||
|
||||
pthread_mutex_unlock(&m);
|
||||
}
|
||||
|
||||
KYTY_CLASS_NO_COPY(SysCS);
|
||||
|
||||
private:
|
||||
SysCS* check_ptr;
|
||||
pthread_mutex_t m;
|
||||
};
|
||||
|
||||
inline void sys_sleep(uint32_t ms)
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000000;
|
||||
nanosleep(&ts, 0);
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSSYNC_H_ */
|
||||
@@ -0,0 +1,147 @@
|
||||
#ifndef SYS_LINUX_INCLUDE_KYTY_SYSTIMER_H_
|
||||
#define SYS_LINUX_INCLUDE_KYTY_SYSTIMER_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_LINUX
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_LINUX"
|
||||
#else
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
struct SysTimeStruct
|
||||
{
|
||||
uint16_t Year;
|
||||
uint16_t Month;
|
||||
uint16_t Day;
|
||||
uint16_t Hour;
|
||||
uint16_t Minute;
|
||||
uint16_t Second;
|
||||
uint16_t Milliseconds;
|
||||
bool is_invalid;
|
||||
};
|
||||
|
||||
struct SysFileTimeStruct
|
||||
{
|
||||
time_t time;
|
||||
bool is_invalid;
|
||||
};
|
||||
|
||||
inline void sys_file_to_system_time_utc(const SysFileTimeStruct& f, SysTimeStruct& t)
|
||||
{
|
||||
struct tm i;
|
||||
|
||||
if (f.is_invalid || !gmtime_r(&f.time, &i))
|
||||
{
|
||||
t.is_invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
t.is_invalid = false;
|
||||
t.Year = i.tm_year + 1900;
|
||||
t.Month = i.tm_mon + 1;
|
||||
t.Day = i.tm_mday;
|
||||
t.Hour = i.tm_hour;
|
||||
t.Minute = i.tm_min;
|
||||
t.Second = (i.tm_sec == 60 ? 59 : i.tm_sec);
|
||||
t.Milliseconds = 0;
|
||||
}
|
||||
|
||||
inline void sys_time_t_to_system(time_t t, SysTimeStruct& s)
|
||||
{
|
||||
SysFileTimeStruct ft;
|
||||
ft.time = t;
|
||||
ft.is_invalid = false;
|
||||
sys_file_to_system_time_utc(ft, s);
|
||||
}
|
||||
|
||||
inline time_t sys_timegm(struct tm* tm)
|
||||
{
|
||||
return timegm(tm);
|
||||
// time_t t = mktime(tm);
|
||||
// return t == (time_t)-1 ? (time_t)-1 : t + localtime(&t)->tm_gmtoff;
|
||||
}
|
||||
|
||||
inline void sys_system_to_file_time_utc(const SysTimeStruct& f, SysFileTimeStruct& t)
|
||||
{
|
||||
struct tm i;
|
||||
|
||||
i.tm_year = f.Year - 1900;
|
||||
i.tm_mon = f.Month - 1;
|
||||
i.tm_mday = f.Day;
|
||||
i.tm_hour = f.Hour;
|
||||
i.tm_min = f.Minute;
|
||||
i.tm_sec = f.Second;
|
||||
|
||||
if (f.is_invalid || (t.time = sys_timegm(&i)) == (time_t)-1)
|
||||
{
|
||||
t.is_invalid = true;
|
||||
} else
|
||||
{
|
||||
t.is_invalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves the current local date and time
|
||||
inline void sys_get_system_time(SysTimeStruct& t)
|
||||
{
|
||||
time_t st;
|
||||
struct tm i;
|
||||
|
||||
if (time(&st) == (time_t)-1 || !localtime_r(&st, &i))
|
||||
{
|
||||
t.is_invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
t.is_invalid = false;
|
||||
t.Year = i.tm_year + 1900;
|
||||
t.Month = i.tm_mon + 1;
|
||||
t.Day = i.tm_mday;
|
||||
t.Hour = i.tm_hour;
|
||||
t.Minute = i.tm_min;
|
||||
t.Second = (i.tm_sec == 60 ? 59 : i.tm_sec);
|
||||
t.Milliseconds = 0;
|
||||
}
|
||||
|
||||
// Retrieves the current system date and time in Coordinated Universal Time (UTC).
|
||||
inline void sys_get_system_time_utc(SysTimeStruct& t)
|
||||
{
|
||||
time_t st;
|
||||
struct tm i;
|
||||
|
||||
if (time(&st) == (time_t)-1 || !gmtime_r(&st, &i))
|
||||
{
|
||||
t.is_invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
t.is_invalid = false;
|
||||
t.Year = i.tm_year + 1900;
|
||||
t.Month = i.tm_mon + 1;
|
||||
t.Day = i.tm_mday;
|
||||
t.Hour = i.tm_hour;
|
||||
t.Minute = i.tm_min;
|
||||
t.Second = (i.tm_sec == 60 ? 59 : i.tm_sec);
|
||||
t.Milliseconds = 0;
|
||||
}
|
||||
|
||||
inline void sys_query_performance_frequency(uint64_t* freq)
|
||||
{
|
||||
*freq = 1000000000LL;
|
||||
}
|
||||
|
||||
inline void sys_query_performance_counter(uint64_t* counter)
|
||||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
*counter = now.tv_sec * 1000000000LL + now.tv_nsec;
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_LINUX_INCLUDE_KYTY_SYSTIMER_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSSTDIO_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSSTDIO_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxStdio.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsStdio.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSSTDIO_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSSTDLIB_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSSTDLIB_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxStdlib.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsStdlib.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSSTDLIB_H_ */
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSSWAPBYTEORDER_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSSWAPBYTEORDER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
inline uint16_t SwapByteOrder16(uint16_t value)
|
||||
{
|
||||
#if KYTY_COMPILER == KYTY_COMPILER_MSVC
|
||||
return _byteswap_ushort(value);
|
||||
#else
|
||||
uint16_t hi = value << 8u;
|
||||
uint16_t lo = value >> 8u;
|
||||
return hi | lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t SwapByteOrder32(uint32_t value)
|
||||
{
|
||||
#if KYTY_COMPILER == KYTY_COMPILER_CLANG
|
||||
return __builtin_bswap32(value);
|
||||
#elif KYTY_COMPILER == KYTY_COMPILER_MSVC
|
||||
return _byteswap_ulong(value);
|
||||
#else
|
||||
uint32_t Byte0 = value & 0x000000FFu;
|
||||
uint32_t Byte1 = value & 0x0000FF00u;
|
||||
uint32_t Byte2 = value & 0x00FF0000u;
|
||||
uint32_t Byte3 = value & 0xFF000000u;
|
||||
return (Byte0 << 24u) | (Byte1 << 8u) | (Byte2 >> 8u) | (Byte3 >> 24u);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64_t SwapByteOrder64(uint64_t value)
|
||||
{
|
||||
#if KYTY_COMPILER == KYTY_COMPILER_CLANG
|
||||
return __builtin_bswap64(value);
|
||||
#elif KYTY_COMPILER == KYTY_COMPILER_MSVC
|
||||
return _byteswap_uint64(value);
|
||||
#else
|
||||
uint64_t Hi = SwapByteOrder32(uint32_t(value));
|
||||
uint32_t Lo = SwapByteOrder32(uint32_t(value >> 32u));
|
||||
return (Hi << 32u) | Lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void SwapByteOrder(T& x)
|
||||
{
|
||||
if (sizeof(x) == 2)
|
||||
{
|
||||
if (std::is_signed_v<T>)
|
||||
{
|
||||
x = std::make_signed_t<T>(SwapByteOrder16(std::make_unsigned_t<uint16_t>(x)));
|
||||
} else
|
||||
{
|
||||
x = SwapByteOrder16(x);
|
||||
}
|
||||
}
|
||||
if (sizeof(x) == 4)
|
||||
{
|
||||
if (std::is_signed_v<T>)
|
||||
{
|
||||
x = std::make_signed_t<T>(SwapByteOrder32(std::make_unsigned_t<uint32_t>(x)));
|
||||
} else
|
||||
{
|
||||
x = SwapByteOrder32(x);
|
||||
}
|
||||
}
|
||||
if (sizeof(x) == 8)
|
||||
{
|
||||
if (std::is_signed_v<T>)
|
||||
{
|
||||
x = std::make_signed_t<T>(SwapByteOrder64(std::make_unsigned_t<uint64_t>(x)));
|
||||
} else
|
||||
{
|
||||
x = SwapByteOrder64(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void NoSwapByteOrder(T& x)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSSWAPBYTEORDER_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSSYNC_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSSYNC_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxSync.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsSync.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSSYNC_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INCLUDE_KYTY_SYS_SYSTIMER_H_
|
||||
#define INCLUDE_KYTY_SYS_SYSTIMER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Kyty/Sys/SysLinuxTimer.h" // IWYU pragma: export
|
||||
#include "Kyty/Sys/SysWindowsTimer.h" // IWYU pragma: export
|
||||
|
||||
#endif /* INCLUDE_KYTY_SYS_SYSTIMER_H_ */
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSDBG_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSDBG_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct sys_dbg_stack_info_t
|
||||
{
|
||||
uintptr_t addr;
|
||||
|
||||
uintptr_t reserved_addr;
|
||||
size_t reserved_size;
|
||||
uintptr_t guard_addr;
|
||||
size_t guard_size;
|
||||
uintptr_t commited_addr;
|
||||
size_t commited_size;
|
||||
|
||||
size_t total_size;
|
||||
};
|
||||
|
||||
using exception_filter_func_t = void (*)(void* addr);
|
||||
|
||||
void sys_stack_walk(void** stack, int* depth);
|
||||
void sys_stack_usage(sys_dbg_stack_info_t& s); // NOLINT(google-runtime-references)
|
||||
void sys_stack_usage_print(sys_dbg_stack_info_t& stack); // NOLINT(google-runtime-references)
|
||||
void sys_get_code_info(uintptr_t* addr, size_t* size);
|
||||
void sys_set_exception_filter(exception_filter_func_t func);
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSDBG_H_ */
|
||||
@@ -0,0 +1,123 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSFILEIO_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSFILEIO_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Sys/SysTimer.h"
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
using KYTY_HANDLE = void*;
|
||||
|
||||
template <typename T>
|
||||
class Vector;
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
enum sys_file_type_t
|
||||
{
|
||||
SYS_FILE_ERROR, // NOLINT(readability-identifier-naming)
|
||||
SYS_FILE_MEMORY_STAT, // NOLINT(readability-identifier-naming)
|
||||
SYS_FILE_FILE, // NOLINT(readability-identifier-naming)
|
||||
SYS_FILE_MEMORY_DYN // NOLINT(readability-identifier-naming)
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
enum sys_file_cache_type_t
|
||||
{
|
||||
SYS_FILE_CACHE_AUTO = 0, // NOLINT(readability-identifier-naming)
|
||||
SYS_FILE_CACHE_RANDOM_ACCESS = 1, // NOLINT(readability-identifier-naming)
|
||||
SYS_FILE_CACHE_SEQUENTIAL_SCAN = 2 // NOLINT(readability-identifier-naming)
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct sys_file_mem_buf_t
|
||||
{
|
||||
uint8_t* base;
|
||||
uint8_t* ptr;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct sys_file_t
|
||||
{
|
||||
sys_file_type_t type;
|
||||
union
|
||||
{
|
||||
KYTY_HANDLE handle;
|
||||
sys_file_mem_buf_t* buf;
|
||||
};
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct sys_file_find_t
|
||||
{
|
||||
String path_with_name;
|
||||
SysFileTimeStruct last_access_time;
|
||||
SysFileTimeStruct last_write_time;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct sys_dir_entry_t
|
||||
{
|
||||
String name;
|
||||
bool is_file;
|
||||
};
|
||||
|
||||
void sys_file_read(void* data, uint32_t size, sys_file_t& f, uint32_t* bytes_read = nullptr); // NOLINT(google-runtime-references)
|
||||
void sys_file_write(const void* data, uint32_t size, sys_file_t& f, uint32_t* bytes_written = nullptr); // NOLINT(google-runtime-references)
|
||||
void sys_file_read_r(void* data, uint32_t size, sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
void sys_file_write_r(const void* data, uint32_t size, sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
sys_file_t* sys_file_create(const String& file_name);
|
||||
sys_file_t* sys_file_open_r(const String& file_name, sys_file_cache_type_t cache_type = SYS_FILE_CACHE_AUTO);
|
||||
sys_file_t* sys_file_open_w(const String& file_name, sys_file_cache_type_t cache_type = SYS_FILE_CACHE_AUTO);
|
||||
sys_file_t* sys_file_open(uint8_t* buf, uint32_t buf_size);
|
||||
sys_file_t* sys_file_create();
|
||||
sys_file_t* sys_file_open_rw(const String& file_name, sys_file_cache_type_t cache_type = SYS_FILE_CACHE_AUTO);
|
||||
void sys_file_close(sys_file_t* f);
|
||||
uint64_t sys_file_size(sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
bool sys_file_seek(sys_file_t& f, uint64_t offset); // NOLINT(google-runtime-references)
|
||||
uint64_t sys_file_tell(sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
bool sys_file_truncate(sys_file_t& f, uint64_t size); // NOLINT(google-runtime-references)
|
||||
void sys_file_write(uint32_t n, sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
void sys_file_write_r(uint32_t n, sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
uint64_t sys_file_size(const String& file_name);
|
||||
bool sys_file_is_error(sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
bool sys_file_io_init();
|
||||
bool sys_file_is_directory_existing(const String& path);
|
||||
bool sys_file_is_file_existing(const String& name);
|
||||
bool sys_file_create_directory(const String& path);
|
||||
bool sys_file_delete_directory(const String& path);
|
||||
bool sys_file_delete_file(const String& name);
|
||||
bool sys_file_flush(sys_file_t& f); // NOLINT(google-runtime-references)
|
||||
SysFileTimeStruct sys_file_get_last_access_time_utc(const String& name);
|
||||
SysFileTimeStruct sys_file_get_last_write_time_utc(const String& name);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
void sys_file_get_last_access_and_write_time_utc(const String& name, SysFileTimeStruct& a, SysFileTimeStruct& w);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
void sys_file_get_last_access_and_write_time_utc(sys_file_t& f, SysFileTimeStruct& a, SysFileTimeStruct& w);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
bool sys_file_set_last_access_time_utc(const String& name, SysFileTimeStruct& access);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
bool sys_file_set_last_write_time_utc(const String& name, SysFileTimeStruct& write);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
bool sys_file_set_last_access_and_write_time_utc(const String& name, SysFileTimeStruct& access, SysFileTimeStruct& write);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
void sys_file_find_files(const String& path, Kyty::Vector<sys_file_find_t>& out);
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
void sys_file_get_dents(const String& path, Kyty::Vector<sys_dir_entry_t>& out);
|
||||
bool sys_file_copy_file(const String& src, const String& dst);
|
||||
bool sys_file_move_file(const String& src, const String& dst);
|
||||
void sys_file_remove_readonly(const String& name);
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSFILEIO_H_ */
|
||||
@@ -0,0 +1,206 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSHEAP_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSHEAP_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
#if 0
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
typedef HANDLE sys_heap_id_t;
|
||||
|
||||
|
||||
inline sys_heap_id_t sys_heap_create()
|
||||
{
|
||||
HANDLE h = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
|
||||
|
||||
EXIT_IF(h == NULL);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
inline sys_heap_id_t sys_heap_deafult()
|
||||
{
|
||||
HANDLE h = GetProcessHeap();
|
||||
|
||||
EXIT_IF(h == NULL);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
inline void* sys_heap_alloc(sys_heap_id_t heap_id, size_t size)
|
||||
{
|
||||
void *m = HeapAlloc(heap_id, HEAP_NO_SERIALIZE, size);
|
||||
|
||||
EXIT_IF(m == 0);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void* sys_heap_realloc(sys_heap_id_t heap_id, void *p, size_t size)
|
||||
{
|
||||
void *m = p ? HeapReAlloc(heap_id, HEAP_NO_SERIALIZE, p, size)
|
||||
: HeapAlloc(heap_id, HEAP_NO_SERIALIZE, size);
|
||||
|
||||
if (m == 0)
|
||||
{
|
||||
EXIT_IF(m == 0);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void sys_heap_free(sys_heap_id_t heap_id, void *p)
|
||||
{
|
||||
bool r = HeapFree(heap_id, HEAP_NO_SERIALIZE, p);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
printf("%" PRIx64"\n", uint64_t(p));
|
||||
EXIT_IF(!r);
|
||||
}
|
||||
}
|
||||
|
||||
inline sys_heap_id_t sys_heap_create_s()
|
||||
{
|
||||
HANDLE h = HeapCreate(0, 0, 0);
|
||||
|
||||
EXIT_IF(h == NULL);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
inline void* sys_heap_alloc_s(sys_heap_id_t heap_id, size_t size)
|
||||
{
|
||||
void *m = HeapAlloc(heap_id, 0, size);
|
||||
|
||||
EXIT_IF(m == 0);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void* sys_heap_realloc_s(sys_heap_id_t heap_id, void *p, size_t size)
|
||||
{
|
||||
void *m = HeapReAlloc(heap_id, 0, p, size);
|
||||
|
||||
EXIT_IF(m == 0);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void sys_heap_free_s(sys_heap_id_t heap_id, void *p)
|
||||
{
|
||||
bool r = HeapFree(heap_id, 0, p);
|
||||
|
||||
EXIT_IF(!r);
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#else
|
||||
|
||||
#include "Kyty/Sys/SysSync.h"
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
using sys_heap_id_t = SysCS *;
|
||||
|
||||
|
||||
inline sys_heap_id_t sys_heap_create()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline sys_heap_id_t sys_heap_deafult()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline void* sys_heap_alloc(sys_heap_id_t /*heap_id*/, size_t size)
|
||||
{
|
||||
//NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
void *m = malloc(size);
|
||||
|
||||
EXIT_IF(m == nullptr);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void* sys_heap_realloc(sys_heap_id_t /*heap_id*/, void *p, size_t size)
|
||||
{
|
||||
//NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
void *m = p != nullptr ? realloc(p, size) : malloc(size);
|
||||
|
||||
if (m == nullptr)
|
||||
{
|
||||
EXIT_IF(m == nullptr);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void sys_heap_free(sys_heap_id_t /*heap_id*/, void *p)
|
||||
{
|
||||
//NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
free(p);
|
||||
}
|
||||
|
||||
inline sys_heap_id_t sys_heap_create_s()
|
||||
{
|
||||
auto *cs = new SysCS;
|
||||
cs->Init();
|
||||
return cs;
|
||||
}
|
||||
|
||||
inline void* sys_heap_alloc_s(sys_heap_id_t heap_id, size_t size)
|
||||
{
|
||||
heap_id->Enter();
|
||||
|
||||
//NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
void *m = malloc(size);
|
||||
|
||||
heap_id->Leave();
|
||||
|
||||
EXIT_IF(m == nullptr);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void* sys_heap_realloc_s(sys_heap_id_t heap_id, void *p, size_t size)
|
||||
{
|
||||
heap_id->Enter();
|
||||
|
||||
//NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
void *m = p != nullptr ? realloc(p, size) : malloc(size);
|
||||
|
||||
heap_id->Leave();
|
||||
|
||||
EXIT_IF(m == nullptr);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline void sys_heap_free_s(sys_heap_id_t heap_id, void *p)
|
||||
{
|
||||
heap_id->Enter();
|
||||
|
||||
//NOLINTNEXTLINE(cppcoreguidelines-no-malloc,hicpp-no-malloc)
|
||||
free(p);
|
||||
|
||||
heap_id->Leave();
|
||||
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSHEAP_H_ */
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSSTDIO_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSSTDIO_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
inline uint32_t sys_vscprintf(const char *format, va_list argptr)
|
||||
{
|
||||
int len = _vscprintf(format, argptr);
|
||||
return len < 0 ? 0 : len;
|
||||
}
|
||||
|
||||
inline uint32_t sys_vsnprintf(char *dest, size_t count, const char *format, va_list args)
|
||||
{
|
||||
int len = _vsnprintf_s(dest, count+1, count, format, args);
|
||||
return len < 0 ? 0 : len;
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSSTDIO_H_ */
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSSTDLIB_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSSTDLIB_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
inline float sys_strtof(const char *nptr, char **endptr)
|
||||
{
|
||||
return strtof(nptr, endptr); // @suppress("Invalid arguments")
|
||||
}
|
||||
|
||||
inline double sys_strtod(const char *nptr, char **endptr)
|
||||
{
|
||||
return strtod(nptr, endptr); // @suppress("Invalid arguments")
|
||||
}
|
||||
|
||||
inline int32_t sys_strtoi32(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return strtol(nptr, endptr, base); // @suppress("Invalid arguments")
|
||||
}
|
||||
|
||||
inline uint32_t sys_strtoui32(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return strtoul(nptr, endptr, base); // @suppress("Invalid arguments")
|
||||
}
|
||||
|
||||
inline int64_t sys_strtoi64(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return _strtoi64(nptr, endptr, base); // @suppress("Invalid arguments")
|
||||
}
|
||||
|
||||
inline uint64_t sys_strtoui64(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return _strtoui64(nptr, endptr, base); // @suppress("Invalid arguments")
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSSTDLIB_H_ */
|
||||
@@ -0,0 +1,78 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSSYNC_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSSYNC_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
constexpr DWORD SYS_CS_SPIN_COUNT = 16;
|
||||
|
||||
class SysCS
|
||||
{
|
||||
public:
|
||||
SysCS() = default;
|
||||
|
||||
void Init()
|
||||
{
|
||||
EXIT_IF(m_check_ptr != nullptr);
|
||||
|
||||
m_check_ptr = this;
|
||||
InitializeCriticalSectionAndSpinCount(&m_cs, SYS_CS_SPIN_COUNT);
|
||||
}
|
||||
|
||||
void Delete()
|
||||
{
|
||||
EXIT_IF(m_check_ptr != this);
|
||||
|
||||
m_check_ptr = nullptr;
|
||||
DeleteCriticalSection(&m_cs);
|
||||
}
|
||||
|
||||
~SysCS() { EXIT_IF(m_check_ptr != nullptr); }
|
||||
|
||||
void Enter()
|
||||
{
|
||||
EXIT_IF(m_check_ptr != this);
|
||||
|
||||
EnterCriticalSection(&m_cs);
|
||||
}
|
||||
|
||||
bool TryEnter()
|
||||
{
|
||||
EXIT_IF(m_check_ptr != this);
|
||||
|
||||
return TryEnterCriticalSection(&m_cs) != 0;
|
||||
}
|
||||
|
||||
void Leave()
|
||||
{
|
||||
EXIT_IF(m_check_ptr != this);
|
||||
|
||||
LeaveCriticalSection(&m_cs);
|
||||
}
|
||||
|
||||
KYTY_CLASS_NO_COPY(SysCS);
|
||||
|
||||
private:
|
||||
SysCS* m_check_ptr = nullptr;
|
||||
CRITICAL_SECTION m_cs {};
|
||||
};
|
||||
|
||||
inline void sys_sleep(uint32_t ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSSYNC_H_ */
|
||||
@@ -0,0 +1,132 @@
|
||||
#ifndef SYS_WIN32_INCLUDE_KYTY_SYSTIMER_H_
|
||||
#define SYS_WIN32_INCLUDE_KYTY_SYSTIMER_H_
|
||||
|
||||
// IWYU pragma: private
|
||||
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
//#error "KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS"
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace Kyty {
|
||||
|
||||
struct SysTimeStruct
|
||||
{
|
||||
uint16_t Year; // NOLINT(readability-identifier-naming)
|
||||
uint16_t Month; // NOLINT(readability-identifier-naming)
|
||||
uint16_t Day; // NOLINT(readability-identifier-naming)
|
||||
uint16_t Hour; // NOLINT(readability-identifier-naming)
|
||||
uint16_t Minute; // NOLINT(readability-identifier-naming)
|
||||
uint16_t Second; // NOLINT(readability-identifier-naming)
|
||||
uint16_t Milliseconds; // NOLINT(readability-identifier-naming)
|
||||
bool is_invalid; // NOLINT(readability-identifier-naming)
|
||||
};
|
||||
|
||||
struct SysFileTimeStruct
|
||||
{
|
||||
FILETIME time;
|
||||
bool is_invalid;
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
inline void sys_file_to_system_time_utc(const SysFileTimeStruct& f, SysTimeStruct& t)
|
||||
{
|
||||
SYSTEMTIME s;
|
||||
|
||||
if (f.is_invalid || (FileTimeToSystemTime(&f.time, &s) == 0))
|
||||
{
|
||||
t.is_invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
t.is_invalid = false;
|
||||
t.Year = s.wYear;
|
||||
t.Month = s.wMonth;
|
||||
t.Day = s.wDay;
|
||||
t.Hour = s.wHour;
|
||||
t.Minute = s.wMinute;
|
||||
t.Second = (s.wSecond == 60 ? 59 : s.wSecond);
|
||||
t.Milliseconds = s.wMilliseconds;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
inline void sys_time_t_to_system(time_t t, SysTimeStruct& s)
|
||||
{
|
||||
SysFileTimeStruct ft {};
|
||||
LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
|
||||
ft.time.dwLowDateTime = static_cast<DWORD>(ll);
|
||||
ft.time.dwHighDateTime = static_cast<DWORD>(static_cast<uint64_t>(ll) >> 32u);
|
||||
ft.is_invalid = false;
|
||||
sys_file_to_system_time_utc(ft, s);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
inline void sys_system_to_file_time_utc(const SysTimeStruct& f, SysFileTimeStruct& t)
|
||||
{
|
||||
SYSTEMTIME s;
|
||||
|
||||
s.wYear = f.Year;
|
||||
s.wMonth = f.Month;
|
||||
s.wDay = f.Day;
|
||||
s.wHour = f.Hour;
|
||||
s.wMinute = f.Minute;
|
||||
s.wSecond = f.Second;
|
||||
s.wMilliseconds = f.Milliseconds;
|
||||
|
||||
t.is_invalid = (f.is_invalid || (SystemTimeToFileTime(&s, &t.time) == 0));
|
||||
}
|
||||
|
||||
// Retrieves the current local date and time
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
inline void sys_get_system_time(SysTimeStruct& t)
|
||||
{
|
||||
SYSTEMTIME s;
|
||||
GetLocalTime(&s);
|
||||
|
||||
t.is_invalid = false;
|
||||
t.Year = s.wYear;
|
||||
t.Month = s.wMonth;
|
||||
t.Day = s.wDay;
|
||||
t.Hour = s.wHour;
|
||||
t.Minute = s.wMinute;
|
||||
t.Second = (s.wSecond == 60 ? 59 : s.wSecond);
|
||||
t.Milliseconds = s.wMilliseconds;
|
||||
}
|
||||
|
||||
// Retrieves the current system date and time in Coordinated Universal Time (UTC).
|
||||
// NOLINTNEXTLINE(google-runtime-references)
|
||||
inline void sys_get_system_time_utc(SysTimeStruct& t)
|
||||
{
|
||||
SYSTEMTIME s;
|
||||
GetSystemTime(&s);
|
||||
|
||||
t.is_invalid = false;
|
||||
t.Year = s.wYear;
|
||||
t.Month = s.wMonth;
|
||||
t.Day = s.wDay;
|
||||
t.Hour = s.wHour;
|
||||
t.Minute = s.wMinute;
|
||||
t.Second = (s.wSecond == 60 ? 59 : s.wSecond);
|
||||
t.Milliseconds = s.wMilliseconds;
|
||||
}
|
||||
|
||||
inline void sys_query_performance_frequency(uint64_t* freq)
|
||||
{
|
||||
LARGE_INTEGER f;
|
||||
QueryPerformanceFrequency(&f);
|
||||
*freq = f.QuadPart;
|
||||
}
|
||||
|
||||
inline void sys_query_performance_counter(uint64_t* counter)
|
||||
{
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
*counter = c.QuadPart;
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SYS_WIN32_INCLUDE_KYTY_SYSTIMER_H_ */
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef INCLUDE_KYTY_CONFIG_H_
|
||||
#define INCLUDE_KYTY_CONFIG_H_
|
||||
|
||||
#define KYTY_PLATFORM_WINDOWS 1
|
||||
#define KYTY_PLATFORM_ANDROID 2
|
||||
#define KYTY_PLATFORM_OSX 3
|
||||
#define KYTY_PLATFORM_IOS 4
|
||||
#define KYTY_PLATFORM_LINUX 5
|
||||
|
||||
#define KYTY_COMPILER_MINGW 1
|
||||
#define KYTY_COMPILER_MSVC 2
|
||||
#define KYTY_COMPILER_GCC 3
|
||||
#define KYTY_COMPILER_CLANG 4
|
||||
|
||||
#define KYTY_LINKER_LINK 1
|
||||
#define KYTY_LINKER_LD 2
|
||||
#define KYTY_LINKER_LLD 3
|
||||
#define KYTY_LINKER_LLD_LINK 4
|
||||
|
||||
#define KYTY_BUILD_DEBUG 1
|
||||
#define KYTY_BUILD_RELEASE 2
|
||||
|
||||
#define KYTY_ENDIAN_BIG 1
|
||||
#define KYTY_ENDIAN_LITTLE 2
|
||||
|
||||
#define KYTY_ABI_ARMEABI 1
|
||||
#define KYTY_ABI_ARMEABI_V7A 2
|
||||
#define KYTY_ABI_ARM64_V8A 3
|
||||
#define KYTY_ABI_X86 4
|
||||
#define KYTY_ABI_X86_64 5
|
||||
#define KYTY_ABI_MIPS 6
|
||||
#define KYTY_ABI_MIPS64 7
|
||||
|
||||
#define KYTY_ARM_FLOAT_SOFT 1
|
||||
#define KYTY_ARM_FLOAT_HARD 2
|
||||
|
||||
#define KYTY_PROJECT_EMPTY 0
|
||||
#define KYTY_PROJECT_EMULATOR 1
|
||||
#define KYTY_PROJECT_BUILD_TOOLS 2
|
||||
|
||||
#include "cmake_config.h"
|
||||
|
||||
#if KYTY_BITNESS == 32
|
||||
#define KYTY_ABI KYTY_ABI_X86
|
||||
#else
|
||||
#define KYTY_ABI KYTY_ABI_X86_64
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_KYTY_CONFIG_H_ */
|
||||
Reference in New Issue
Block a user