Got SmartOStreams kinda working!
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#ifndef _NB_DATASINK
|
||||
#define _NB_DATASINK
|
||||
|
||||
namespace nb {
|
||||
|
||||
template <typename T>
|
||||
class SinkBase {
|
||||
using InputType = T;
|
||||
public:
|
||||
virtual bool in(const T&) = 0;
|
||||
|
||||
protected:
|
||||
SinkBase();
|
||||
|
||||
};
|
||||
|
||||
/* template <typename T>
|
||||
class Sink : public SinkBase {
|
||||
public:
|
||||
Sink& operator=(const Sink&) = 0;
|
||||
|
||||
template<typename U>
|
||||
virtual bool in(const U&) = 0;
|
||||
|
||||
protected:
|
||||
Sink();
|
||||
|
||||
}; */
|
||||
|
||||
template <typename T>
|
||||
class SourceBase {
|
||||
using OutputType = T;
|
||||
public:
|
||||
SourceBase& operator=(const SourceBase&) = 0;
|
||||
|
||||
virtual bool out(T*) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
SourceBase();
|
||||
SinkBase<T>* _sink;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Pipe : public SinkBase<T>, public SourceBase<T>{
|
||||
using Input = SourceBase<T>;
|
||||
using Output = SinkBase<T>;
|
||||
public:
|
||||
Pipe(Sink<T>& sink) : Input::_sink{&sink} {}
|
||||
|
||||
bool in(const T&) = 0;
|
||||
|
||||
protected:
|
||||
using Input::_sink;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* template <typename T>
|
||||
class Source : SourceBase {
|
||||
public:
|
||||
Source& operator=(const Source&) = 0;
|
||||
|
||||
template<typename U>
|
||||
virtual bool out(const U&) = 0;
|
||||
|
||||
protected:
|
||||
Source();
|
||||
|
||||
}; */
|
||||
|
||||
} // namespace nb
|
||||
#endif // _NB_DATASINK
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
#ifndef _NB_LOGGER
|
||||
#define _NB_LOGGER
|
||||
|
||||
#include <chrono>
|
||||
#include <ostream>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "SmartStreams.hpp"
|
||||
#include "ThreadSafeQueue.hpp"
|
||||
|
||||
namespace nb {
|
||||
|
||||
typedef std::chrono::time_point<
|
||||
std::chrono::system_clock,
|
||||
std::chrono::nanoseconds
|
||||
> LoggerTimePoint;
|
||||
|
||||
struct LogEvent{
|
||||
const LoggerTimePoint time;
|
||||
const unsigned char lvl;
|
||||
const std::string msg;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Logger {
|
||||
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
|
||||
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
|
||||
public:
|
||||
Logger();
|
||||
|
||||
bool isRunning() const;
|
||||
unsigned int count() const;
|
||||
|
||||
bool run();
|
||||
bool stop();
|
||||
LogEvent popProcess();
|
||||
LogEvent popDelete();
|
||||
void flush();
|
||||
void deleteAll();
|
||||
void msg(const std::string&, uint8_t lvl=0);
|
||||
void warn(const std::string&, uint8_t lvl=1);
|
||||
void warn(const std::exception&, uint8_t lvl=1);
|
||||
void error(const std::string&, uint8_t lvl=0xFF);
|
||||
void error(const std::exception&, uint8_t lvl=0xFF);
|
||||
|
||||
|
||||
protected:
|
||||
virtual void process(const LogEvent&);
|
||||
|
||||
const LogProcessFunctionMap _function_map;
|
||||
|
||||
ThreadsafeQueue<LogEvent> _queue;
|
||||
T* _ostream;
|
||||
// std::condition_variable _cond;
|
||||
// mutable std::mutex _mutex;
|
||||
mutable std::mutex _runningMutex;
|
||||
bool _running;
|
||||
std::shared_ptr<std::thread> _runningThread = nullptr;
|
||||
};
|
||||
|
||||
} // namespace nb
|
||||
#endif // _NB_LOGGER
|
||||
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
#ifndef _NB_SMARTSTREAM
|
||||
#define _NB_SMARTSTREAM
|
||||
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace nb {
|
||||
|
||||
typedef std::pair<unsigned int, std::string> SmartTextKV;
|
||||
|
||||
//template<typename T=std::string>
|
||||
struct SmartText {
|
||||
std::string msg;
|
||||
SmartTextKV kv = {0, ""};
|
||||
};
|
||||
|
||||
typedef std::string (*SmartTextFormatter)(std::string, std::string);
|
||||
|
||||
typedef std::unordered_map<unsigned int, SmartTextFormatter> SmartFormatMap;
|
||||
|
||||
template<typename ST, typename Derived>
|
||||
class SmartOStreamBaseImpl;
|
||||
|
||||
template<typename ST, typename Derived=void>
|
||||
class SmartOStream;
|
||||
|
||||
template<typename ST, typename Derived>
|
||||
class SmartOStreamBaseImpl {
|
||||
public:
|
||||
virtual void process(const SmartText&) = 0;
|
||||
|
||||
static const SmartFormatMap Formatters;
|
||||
using StreamType = SmartOStream<ST>;
|
||||
protected:
|
||||
SmartOStreamBaseImpl(StreamType& stream) : _ostream(&stream) {}
|
||||
StreamType* _ostream;
|
||||
};
|
||||
|
||||
template<typename C, typename T, typename Derived>
|
||||
class SmartOStreamBaseImpl<std::basic_ostream<C, T>, Derived> {
|
||||
public:
|
||||
virtual void process(const SmartText&) = 0;
|
||||
|
||||
static const SmartFormatMap Formatters;
|
||||
using StreamType = std::basic_ostream<C, T>;
|
||||
protected:
|
||||
SmartOStreamBaseImpl(StreamType& stream) : _ostream(&stream) {}
|
||||
StreamType* _ostream;
|
||||
};
|
||||
|
||||
|
||||
template<typename StreamType, typename Derived>
|
||||
class SmartOStream : public SmartOStreamBaseImpl<StreamType, Derived> {
|
||||
template <typename ST, typename D, typename U>
|
||||
friend SmartOStream<ST, D>& operator<<(SmartOStream<ST, D>&, const U&);
|
||||
|
||||
public:
|
||||
StreamType* getStream() const { return _ostream; }
|
||||
|
||||
template <typename X>
|
||||
void process(const X&);
|
||||
|
||||
void process(const SmartText&);
|
||||
|
||||
static const SmartFormatMap Formatters;
|
||||
using Base = SmartOStreamBaseImpl<StreamType, Derived>;
|
||||
|
||||
protected:
|
||||
using Base::Base;
|
||||
using Base::_ostream;
|
||||
|
||||
static std::string defaultFormatter(std::string msg, std::string fmt) {
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ST, typename D>
|
||||
const SmartFormatMap SmartOStream<ST, D>::Formatters = {
|
||||
{0, defaultFormatter}
|
||||
};
|
||||
|
||||
template <typename ST, typename D, typename U>
|
||||
SmartOStream<ST, D>& operator<<(SmartOStream<ST, D>& stream, const U& msg) {
|
||||
static_cast<D*>(&stream)->process(msg);
|
||||
return stream;
|
||||
}
|
||||
|
||||
template<typename ST, typename D>
|
||||
void SmartOStream<ST, D>::process(const SmartText& msg) {
|
||||
try {
|
||||
*_ostream << D::Formatters.at(msg.kv.first)(msg.msg, msg.kv.second);
|
||||
} catch (const std::out_of_range& e) {
|
||||
*_ostream << D::Formatters.at(0)(msg.msg, msg.kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ST, typename D>
|
||||
template<typename X>
|
||||
void SmartOStream<ST, D>::process(const X& msg) {
|
||||
*_ostream << msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // _NB_SMARTSTREAM
|
||||
Reference in New Issue
Block a user