Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/helpers/CSingleThreadWrapper.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/helpers/CSingleThreadWrapper.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,91 @@ +#pragma once + +#include "ThreadUtils.h" +#include "rethrow.h" + +namespace ThreadUtils { + + // OLD single thread wrapper class used only by old WMA input + // Modern code should use cmdThread which is all kinds of prettier + template<typename TBase, bool processMsgs = false> + class CSingleThreadWrapper : protected CVerySimpleThread { + private: + protected: + class command { + protected: + command() : m_abort(), m_completionEvent() {} + virtual void executeImpl(TBase &) {} + virtual ~command() {} + public: + void execute(TBase & obj) { + m_rethrow.exec( [this, &obj] {executeImpl(obj); } ); + SetEvent(m_completionEvent); + } + void rethrow() const { + m_rethrow.rethrow(); + } + CRethrow m_rethrow; + HANDLE m_completionEvent; + abort_callback * m_abort; + }; + + typedef std::function<void (TBase&) > func_t; + + class command2 : public command { + public: + command2( func_t f ) : m_func(f) {} + void executeImpl(TBase & obj) { + m_func(obj); + } + private: + + func_t m_func; + }; + + typedef pfc::rcptr_t<command> command_ptr; + + CSingleThreadWrapper() { + m_completionEvent.create(true,false); + this->StartThread(); + //start(); + } + + ~CSingleThreadWrapper() { + m_threadAbort.abort(); + this->WaitTillThreadDone(); + } + + void invokeCommand2( func_t f, abort_callback & abort) { + auto c = pfc::rcnew_t<command2>(f); + invokeCommand( c, abort ); + } + void invokeCommand(command_ptr cmd, abort_callback & abort) { + abort.check(); + m_completionEvent.set_state(false); + pfc::vartoggle_t<abort_callback*> abortToggle(cmd->m_abort, &abort); + pfc::vartoggle_t<HANDLE> eventToggle(cmd->m_completionEvent, m_completionEvent.get() ); + m_commands.Add(cmd); + m_completionEvent.wait_for(-1); + //WaitAbortable(m_completionEvent.get(), abort); + cmd->rethrow(); + } + + private: + void ThreadProc() { + TRACK_CALL_TEXT("CSingleThreadWrapper entry"); + try { + TBase instance; + for(;;) { + command_ptr cmd; + if (processMsgs) m_commands.Get_MsgLoop(cmd, m_threadAbort); + else m_commands.Get(cmd, m_threadAbort); + cmd->execute(instance); + } + } catch(...) {} + if (processMsgs) ProcessPendingMessages(); + } + win32_event m_completionEvent; + CObjectQueue<command_ptr> m_commands; + abort_callback_impl m_threadAbort; + }; +} \ No newline at end of file
