2021-05-10 08:23:02 +08:00
|
|
|
#pragma once
|
2022-10-02 04:29:51 +08:00
|
|
|
#include <new> // for in-place constructors, for Vector/StackVector
|
|
|
|
#include <utility> // for std::move, std::forward
|
|
|
|
#include <stdint.h> // for integer types
|
|
|
|
#include <stddef.h> // for std::size_t
|
|
|
|
#include <stdlib.h> // for abort
|
|
|
|
#include <stdarg.h> // for string format methods
|
2022-10-23 14:18:34 +08:00
|
|
|
#include <stdio.h> // for vsnprintf
|
2022-10-02 04:29:51 +08:00
|
|
|
#include <math.h> // for standard lib math functions used in blah_calc.h
|
2022-02-12 07:20:07 +08:00
|
|
|
|
2022-10-02 04:29:51 +08:00
|
|
|
// Numeric Types
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
using i8 = int8_t;
|
|
|
|
using i16 = int16_t;
|
|
|
|
using i32 = int32_t;
|
|
|
|
using i64 = int64_t;
|
|
|
|
using u8 = uint8_t;
|
|
|
|
using u16 = uint16_t;
|
|
|
|
using u32 = uint32_t;
|
|
|
|
using u64 = uint64_t;
|
|
|
|
using f32 = float;
|
|
|
|
using f64 = double;
|
|
|
|
using size_t = std::size_t;
|
|
|
|
}
|
2021-05-10 08:23:02 +08:00
|
|
|
|
2022-08-22 03:25:36 +08:00
|
|
|
// Aborts
|
|
|
|
#ifdef _WIN32
|
|
|
|
#define BLAH_ABORT() do { __debugbreak(); ::exit(1); } while(0)
|
|
|
|
#else
|
|
|
|
#define BLAH_ABORT() ::abort()
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Assert Behavior (abort in debug)
|
2021-05-10 08:23:02 +08:00
|
|
|
#if defined(DEBUG) || defined(_DEBUG)
|
2022-08-22 03:25:36 +08:00
|
|
|
#define BLAH_ASSERT_BEHAVIOR() BLAH_ABORT()
|
2021-05-10 08:23:02 +08:00
|
|
|
#else
|
2022-08-22 03:25:36 +08:00
|
|
|
#define BLAH_ASSERT_BEHAVIOR()
|
2021-05-10 08:23:02 +08:00
|
|
|
#endif
|
|
|
|
|
2022-08-22 03:25:36 +08:00
|
|
|
// Asserts
|
|
|
|
#define BLAH_ASSERT(condition, msg) \
|
|
|
|
do { \
|
|
|
|
if (!(condition)) { \
|
|
|
|
Blah::Log::error("%s\n\tin %s:%d", (msg), __FILE__, __LINE__); \
|
|
|
|
BLAH_ASSERT_BEHAVIOR(); \
|
|
|
|
} \
|
|
|
|
} while(0)
|
|
|
|
#define BLAH_ASSERT_FMT(condition, msg, ...) \
|
|
|
|
do { \
|
|
|
|
if (!(condition)) { \
|
|
|
|
Blah::Log::error(msg "\n\tin %s:%d", __VA_ARGS__, __FILE__, __LINE__); \
|
|
|
|
BLAH_ASSERT_BEHAVIOR(); \
|
|
|
|
} \
|
|
|
|
} while(0)
|
|
|
|
|
2022-02-12 07:20:07 +08:00
|
|
|
// Logging
|
|
|
|
namespace Blah
|
|
|
|
{
|
2021-05-10 08:23:02 +08:00
|
|
|
namespace Log
|
|
|
|
{
|
|
|
|
enum class Category
|
|
|
|
{
|
|
|
|
Info,
|
|
|
|
Warning,
|
|
|
|
Error
|
|
|
|
};
|
|
|
|
|
2022-02-12 07:20:07 +08:00
|
|
|
constexpr int max_length = 1024;
|
|
|
|
|
2021-05-10 08:23:02 +08:00
|
|
|
void info(const char* message, ...);
|
|
|
|
void warn(const char* message, ...);
|
|
|
|
void error(const char* message, ...);
|
|
|
|
}
|
2022-02-12 07:20:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Initializer list, required for Vector/StackVector
|
|
|
|
#include <initializer_list>
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
template<typename T> using InitializerList = std::initializer_list<T>;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Functional, for App Callbacks
|
|
|
|
#ifndef BLAH_NO_FUNCTIONAL
|
|
|
|
#include <functional>
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
template<class Ret, class...Args> using Func = std::function<Ret(Args...)>;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
template<class Ret, class...Args> using Func = Ret(*)(Args...);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Ref Counter, for Graphics & Input Resources
|
|
|
|
#ifndef BLAH_NO_SHARED_PTR
|
|
|
|
#include <memory>
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
template<typename T> using Ref = std::shared_ptr<T>;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
namespace Blah
|
|
|
|
{
|
2022-02-12 16:18:08 +08:00
|
|
|
struct RefDel { virtual ~RefDel() = default; virtual void delete_it(void* it) = 0; };
|
|
|
|
template<class Y> struct RefDelOf : public RefDel { void delete_it(void* it) { delete (Y*)it; } };
|
|
|
|
|
2022-02-12 07:20:07 +08:00
|
|
|
template<typename T>
|
|
|
|
class Ref
|
|
|
|
{
|
|
|
|
template<class Y> friend class Ref;
|
|
|
|
private:
|
2022-02-12 16:18:08 +08:00
|
|
|
inline static RefDelOf<T> del;
|
2022-02-12 07:20:07 +08:00
|
|
|
|
2022-02-12 16:18:08 +08:00
|
|
|
T* m_obj = nullptr;
|
|
|
|
u32* m_num = nullptr;
|
|
|
|
RefDel* m_del = nullptr;
|
2022-02-12 07:20:07 +08:00
|
|
|
|
2022-02-12 16:18:08 +08:00
|
|
|
Ref(T* o, u32* n, RefDel* d) : m_obj(o), m_num(n), m_del(d) {}
|
2022-02-12 07:20:07 +08:00
|
|
|
|
2022-02-12 16:18:08 +08:00
|
|
|
void copy(const Ref& rhs) { m_obj = rhs.m_obj; m_num = rhs.m_num; m_del = rhs.m_del; }
|
|
|
|
void zero() { m_obj = nullptr; m_num = nullptr; m_del = nullptr; }
|
|
|
|
void steal(Ref& rhs) { copy(rhs); rhs.zero(); }
|
|
|
|
void increment() { if (m_num) (*m_num)++; }
|
2022-02-12 07:20:07 +08:00
|
|
|
|
2022-02-12 16:18:08 +08:00
|
|
|
public:
|
|
|
|
Ref() = default;
|
|
|
|
template<class Y>
|
|
|
|
Ref(Y* instance) : Ref(static_cast<T*>(instance), new u32(1), &Ref<Y>::del) {}
|
|
|
|
Ref(const Ref& rhs) { copy(rhs); increment(); }
|
|
|
|
Ref(Ref&& rhs) { steal(rhs); }
|
2022-02-12 07:20:07 +08:00
|
|
|
~Ref() { reset(); }
|
|
|
|
|
2022-02-12 16:18:08 +08:00
|
|
|
Ref& operator=(const Ref& rhs) { if (this != &rhs) { reset(); copy(rhs); increment(); } return *this; }
|
|
|
|
Ref& operator=(Ref&& rhs) { if (this != &rhs) { reset(); steal(rhs); } return *this; }
|
|
|
|
|
|
|
|
void reset() { if (m_num && --(*m_num) <= 0) { m_del->delete_it(m_obj); delete m_num; } zero(); }
|
|
|
|
int use_count() const { return (m_num ? (*m_num) : 0); }
|
|
|
|
T* get() const { return m_obj; }
|
|
|
|
T* operator->() const { return m_obj; }
|
|
|
|
operator bool() const { return m_num && (*m_num) > 0; }
|
|
|
|
template<class Y> bool operator==(const Ref<Y>& rhs) const { return m_num == rhs.m_num; }
|
|
|
|
template<class Y> bool operator!=(const Ref<Y>& rhs) const { return m_num != rhs.m_num; }
|
|
|
|
template<class Y> operator Ref<Y>() { increment(); return Ref<Y>(static_cast<Y*>(m_obj), m_num, m_del); }
|
2022-02-12 07:20:07 +08:00
|
|
|
};
|
|
|
|
}
|
2022-08-22 03:25:36 +08:00
|
|
|
#endif
|