// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
#pragma once
#ifndef COMMON_H
#define COMMON_H
#include "TaskManager.h"
#include <functional>
#include <vector>
#include <mutex>
enum LogLevel
{
LL_Trace,
LL_Info,
LL_Debug,
LL_Warn,
LL_Error
};
void Log(enum LogLevel a_level, const char* a_fmt, ...);
void loadFile(const char* a_fileName, std::vector<uint8_t>& a_output);
void loadFileAsync(TaskManager& a_mgr, const char* a_fileName, std::function<void(const std::vector<uint8_t>&)> a_callback);
#if 0
struct mat4
{
mat4& operator=(const float* other)
{
for (int i = 0; i < 16; i++)
m[i] = other[i];
return *this;
}
union
{
struct
{
float m00, m01, m02, m03;
float m10, m11, m12, m13;
float m20, m21, m22, m23;
float m30, m31, m32, m33;
};
float m[16];
} __attribute__((aligned(16)));
};
struct mat3
{
mat3& operator=(const mat3& a_other)
{
for (int i = 0; i < 12; i++)
m[i] = a_other.m[i];
return *this;
}
mat3& operator=(const float* a_flt3x3)
{
for (int i = 0; i < 9; i++)
m[(i/3)*4+(i%3)] = a_flt3x3[i];
return *this;
}
union
{
struct
{
float m00, m01, m02, dummy01;
float m10, m11, m12, dummy02;
float m20, m21, m22, dummy03;
};
float m[12];
};
};
#endif
struct vec2f
{
union
{
struct
{
float x, y;
};
float v[2];
};
};
struct vec3f
{
union
{
struct
{
float x, y, z;
};
float v[3];
};
};
struct vec4f
{
union
{
struct
{
float x, y, z, w;
};
float v[4];
};
};
typedef int sampler2D;
template <typename ...T> struct bad_food : std::false_type {};
// Need to use inheritance from unique_lock to make it compatible with using with condition_variables
class ScopeLock : public std::unique_lock<std::mutex>
{
public:
ScopeLock(std::mutex& a_mutex) : std::unique_lock<std::mutex>(a_mutex) {}
template <typename F>
void unlocked(F&& a_func)
{
unlock();
a_func();
lock();
}
};
template <typename T>
struct GenericFactoryItem
{
GenericFactoryItem(const char* a_name, T a_value)
: m_name(a_name), m_value(a_value), m_next(getFactoryHead())
{
getFactoryHead(this);
}
const char* m_name;
T m_value;
const GenericFactoryItem<T>* m_next;
static const GenericFactoryItem<T>* getFactoryHead(const GenericFactoryItem<T>* newValue = nullptr);
};
// It shouldn't matter, but for XCode this needed to not be inline in the definition above
template <typename T>
const GenericFactoryItem<T>* GenericFactoryItem<T>::getFactoryHead(const GenericFactoryItem<T>* newValue)
{
static const GenericFactoryItem<T>* s_factoryHead = nullptr;
if (newValue != nullptr)
s_factoryHead = newValue;
return s_factoryHead;
}
#endif // COMMON_H