6 #ifndef SL_LOG_CORE_HPP
7 #define SL_LOG_CORE_HPP
49 template <Record TRecord>
58 using SinkContainer_t = std::vector<std::unique_ptr<ISink_t>>;
66 m_Worker{ m_WorkerInstruction, m_Records, m_SinkMx, m_Sinks }
68 m_WorkerFuture = std::async(std::launch::async, m_Worker);
79 m_WorkerInstruction = Worker::Instruction::quit;
80 m_WorkerFuture.wait();
84 m_WorkerInstruction = Worker::Instruction::forceQuit;
114 if (m_WorkerInstruction == Worker::Instruction::run)
116 m_Records.
push(std::move(record));
128 template <std::derived_from<ISink_t> TSink,
class... TArgs>
129 requires std::constructible_from<TSink, TArgs...>
132 auto& ref = makeSinkImpl<TSink>(std::forward<TArgs>(args)...);
147 template <std::derived_from<ISink_t> TSink,
class... TArgs>
148 requires std::constructible_from<TSink, TArgs...>
151 auto& ref = makeSinkImpl<TSink>(std::forward<TArgs>(args)...);
163 std::scoped_lock lock{ m_SinkMx };
165 if (
auto itr = std::ranges::find(m_Sinks, &sink, &std::unique_ptr<ISink_t>::get); itr != std::end(m_Sinks))
168 swap(*itr, m_Sinks.back());
169 m_Sinks.resize(std::size(m_Sinks) - 1);
179 enum class Instruction
187 const std::atomic<Instruction>& instruction,
188 RecordQueue_t& records,
190 const SinkContainer_t& sinks
192 m_Instruction{ instruction },
193 m_Records{ records },
199 void operator ()()
const
201 for (
auto instruction = m_Instruction.load();
202 instruction != Instruction::forceQuit &&
203 (instruction != Instruction::quit || !std::empty(m_Records));
204 instruction = m_Instruction)
206 if (
auto optRecord = m_Records.take(std::chrono::milliseconds{ 200 }))
208 std::scoped_lock lock{ m_SinkMx };
213 [&record = *optRecord](
auto& sink)
223 const std::atomic<Instruction>& m_Instruction;
225 RecordQueue_t& m_Records;
227 std::mutex& m_SinkMx;
228 const SinkContainer_t& m_Sinks;
231 RecordQueue_t m_Records;
234 SinkContainer_t m_Sinks;
236 std::atomic<typename Worker::Instruction> m_WorkerInstruction{ Worker::Instruction::run };
238 std::future<void> m_WorkerFuture;
240 template <std::derived_from<ISink_t> TSink,
class... TArgs>
241 requires std::constructible_from<TSink, TArgs...>
242 TSink& makeSinkImpl(TArgs&&... args)
244 auto sink = std::make_unique<TSink>(std::forward<TArgs>(args)...);
246 std::scoped_lock lock{ m_SinkMx };
247 m_Sinks.emplace_back(std::move(sink));
The central point of the whole library. Needs to be instantiated at least once.
Definition: Core.hpp:51
std::remove_cvref_t< TRecord > Record_t
Definition: Core.hpp:53
requires std::constructible_from< TSink, TArgs... > ScopedSinkDisabling< Record_t, TSink > makeDisabledSink(TArgs &&... args)
Creates Sink disabled and registers it at this Core instance.
Definition: Core.hpp:149
Core(const Core &)=delete
Deleted copy constructor.
~Core() noexcept
Destructor.
Definition: Core.hpp:75
Core(Core &&)=delete
Deleted move constructor.
Core() noexcept
Default Constructor.
Definition: Core.hpp:65
void log(Record_t &&record)
Queues the Record internally.
Definition: Core.hpp:111
bool removeSink(const ISink_t &sink)
Removes the given Sink and destroys it.
Definition: Core.hpp:161
requires std::constructible_from< TSink, TArgs... > TSink & makeSink(TArgs &&... args)
Creates Sink and registers it at this Core instance.
Definition: Core.hpp:130
Core & operator=(const Core &)=delete
Deleted copy assign operator.
Sink interface class.
Definition: ISink.hpp:29
void push(Record_t record)
Pushes Record s to the internal queue.
Definition: RecordQueue.hpp:43
Wrapper class which disables Sinks on construction and enables them on destruction.
Definition: ISink.hpp:95
Definition: BasicSink.hpp:22