// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
#pragma once
#ifndef COMMON_H
#define COMMON_H
#include "Log.h"
#include <functional>
#include <vector>
#include <mutex>
#include "Context.h"
class Dispatchable
{
public:
virtual void dispatch() const = 0;
};
class Finalizable
{
public:
// Calls all the cleanup functions
virtual ~Finalizable();
// Finalizers
typedef std::function<void()> CleanupFunction;
void addCleanupCallback(const CleanupFunction& a_callback);
private:
std::vector<CleanupFunction> m_cleanupFunctions;
};
// 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();
}
};
class AutoLock : public Finalizable
{
public:
AutoLock(std::mutex& a_mutex) { a_mutex.lock(); addCleanupCallback([&](){a_mutex.unlock();}); }
};
// Alternative implementation
class AutoLockClassic
{
public:
AutoLockClassic(std::mutex& a_mutex) : m_mutex(a_mutex) { m_mutex.lock(); }
~AutoLockClassic() { m_mutex.unlock(); }
std::mutex& m_mutex;
};
class StackOnlyClass
{
private:
void *operator new(size_t) = delete;
};
class HeapOnlyClass
{
public:
static HeapOnlyClass *create() { return new HeapOnlyClass; }
static void destroy(HeapOnlyClass *a_obj) { delete a_obj; }
private:
HeapOnlyClass() {}
~HeapOnlyClass() {}
};
#include "UnitTest.h"
#endif // COMMON_H