189 lines
7.9 KiB
C++
189 lines
7.9 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: IIOProcessor.hpp
|
|
Date: 2022-6-6
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
namespace Aurora::IO::Loop
|
|
{
|
|
struct ILoopQueue;
|
|
struct ILoopSource;
|
|
}
|
|
|
|
namespace Aurora::IO
|
|
{
|
|
struct IIOProcessor
|
|
{
|
|
// Local thread:
|
|
|
|
// note: IOProcessors running over an AuAsync runner or is getting pumped by an external loop queue (NewIOProcessor(...), NewIOProcessorOnThread(...)) need not use the following apis:
|
|
|
|
virtual AuUInt32 TryTick () = 0;
|
|
virtual AuUInt32 RunTick () = 0;
|
|
virtual AuUInt32 RunTickEx (AuUInt32 dwTimeout) = 0;
|
|
virtual AuUInt32 TickFor (const AuSPtr<IIOProcessorItem> &pIoEvent) = 0;
|
|
|
|
/**
|
|
* @brief force a tick
|
|
*/
|
|
virtual AuUInt32 ManualTick () = 0;
|
|
|
|
/**
|
|
* @brief to be used with bTickOnly primarily. wakes up the thread at a set frequency.
|
|
*/
|
|
virtual AuUInt64 SetRefreshRate (AuUInt64 ns) = 0;
|
|
|
|
/**
|
|
* @brief to be used with bTickOnly primarily. wakes up the thread at a set frequency.
|
|
*/
|
|
virtual bool HasRefreshRate () = 0;
|
|
|
|
/**
|
|
* @brief returns the aurora threadid of the intended caller (see: AuThreads::GetThreadId())
|
|
*/
|
|
virtual AuUInt64 GetOwnedThreadId () = 0;
|
|
|
|
// The following apis are thread safe:
|
|
|
|
/**
|
|
* @brief Used to poll if there are any items worth [try/blocking] ticking over.
|
|
* @return returns true if there are callbacks, watches, or other registered work available.
|
|
* @note you can use me as a while (AuIsThreadRunning() && pIoProcessor->[IsAlive/HasItems]()) { pIoProcessor->[RunTickEx(uTimeout); }
|
|
*/
|
|
virtual bool HasItems() = 0;
|
|
|
|
|
|
// the following are apis used to register triggers (usually loop sources) on the thread/processor/loop queue/whatever
|
|
|
|
/**
|
|
* @brief low level wait api
|
|
*/
|
|
virtual AuSPtr<IIOProcessorItem> StartIOWatch (const AuSPtr<IIOWaitableItem> &pSource, const AuSPtr<IIOEventListener> &pEventListener) = 0;
|
|
|
|
/**
|
|
* @brief low level wait api
|
|
*/
|
|
virtual AuSPtr<IIOProcessorItem> StartIOWatchEx (const AuSPtr<IIOWaitableItem> &pSource, const AuSPtr<IIOEventListener> &pEventListener, bool bSingleshot) = 0;
|
|
|
|
/**
|
|
* @brief low level wait api with simple callback
|
|
*/
|
|
virtual AuSPtr<IIOProcessorItem> StartSimpleIOWatch (const AuSPtr<IIOWaitableItem> &pSource, const AuSPtr<IIOSimpleEventListener> &pEventListener) = 0;
|
|
|
|
/**
|
|
* @brief low level wait api with simple callback
|
|
*/
|
|
virtual AuSPtr<IIOProcessorItem> StartSimpleIOWatchEx(const AuSPtr<IIOWaitableItem> &pSource, const AuSPtr<IIOSimpleEventListener> &pEventListener, bool bSingleshot) = 0;
|
|
|
|
/**
|
|
* @brief Registers a callback given a loopsource (multi-trigger)
|
|
* @param pSource
|
|
* @param pEventListener
|
|
* @return
|
|
*/
|
|
virtual AuSPtr<IIOProcessorItem> StartSimpleLSWatch (const AuSPtr<Loop::ILoopSource> &pSource, const AuSPtr<IIOSimpleEventListener> &pEventListener) = 0;
|
|
|
|
/**
|
|
* @brief Registers an optionally singleshot callback given a loopsource
|
|
* @param pSource
|
|
* @param pEventListener
|
|
* @param dwMsTimeout optional timeout
|
|
* @return
|
|
*/
|
|
virtual AuSPtr<IIOProcessorItem> StartSimpleLSWatchEx(const AuSPtr<Loop::ILoopSource> &pSource, const AuSPtr<IIOSimpleEventListener> &pEventListener, bool bSingleshot, AuUInt32 dwMsTimeout = 0) = 0;
|
|
|
|
// general purpose work callbacks
|
|
|
|
/**
|
|
* @brief Dispatches an abortable callback to the processor thread
|
|
* @param pWork
|
|
* @return
|
|
*/
|
|
virtual bool SubmitIOWorkItem (const AuSPtr<IIOProcessorWorkUnit> &pWork) = 0;
|
|
|
|
// wake up
|
|
|
|
/**
|
|
* @brief you almost certainly will not need me. so far i've come across one legitmate use case for glib-io interop and thats about it.
|
|
*/
|
|
virtual void WakeupThread () = 0;
|
|
|
|
// io sequence callbacks
|
|
|
|
/**
|
|
* @brief Register an inter-frame callback indicating point of execution throughout the [START](optional [yield])[IO][IO TICK][WORK ITEMS][EPILOGUE][END OF FRAME] frame
|
|
* @param eventListener
|
|
* @return
|
|
*/
|
|
virtual bool AddEventListener (const AuSPtr<IIOProcessorEventListener> &pEventListener) = 0;
|
|
|
|
/**
|
|
* @brief Deregisters an inter-frame callback listener
|
|
* @param pEventListener
|
|
*/
|
|
virtual void RemoveEventListener (const AuSPtr<IIOProcessorEventListener> &pEventListener) = 0;
|
|
|
|
// factories backed by this processor to provide additional functionality
|
|
|
|
/**
|
|
* @brief provides an IO pipe processor for creating pipe requests
|
|
* @return
|
|
*/
|
|
virtual AuSPtr<IIOPipeProcessor> ToPipeProcessor () = 0;
|
|
|
|
// internal and utility apis
|
|
|
|
/**
|
|
* @brief Utility proprety access to the underlying IO wait surface: a loop queue
|
|
* @return
|
|
* @warning Do not use me unless you know what you're doing.
|
|
* There is very little reason to pull the underlying loop queue from here.
|
|
* You are probably doing something wrong. IOProcessors are meant to sit on top of
|
|
* queues as an abstraction layer for intelligent work dispatch, global stream processing
|
|
* and dispatch of io work callbacks. pulling a loopqueue from such a layer of abstraction
|
|
* would be like pulling the state of an upcoming WaitMultipleObjects call; it makes no sense.
|
|
*
|
|
* [note to future deadbeat maintainers: that doesnt mean you should remove it either]
|
|
*/
|
|
virtual AuSPtr<Loop::ILoopQueue> ToQueue () = 0;
|
|
|
|
virtual bool MultiplexRefreshRateWithIOEvents() = 0;
|
|
|
|
/**
|
|
* @brief resets the io processors footprint in ::ToQueue()
|
|
*/
|
|
virtual void ReleaseAllWatches () = 0;
|
|
|
|
/**
|
|
* @warning: do not use me. this is a niche hack for nested ui modal loops.
|
|
*/
|
|
virtual bool ConfigureNoDeferredTicks(bool bOption) = 0;
|
|
};
|
|
|
|
/**
|
|
* @brief Creates an IOProcessor to execute tasks on a given loop queue
|
|
* @param bTickOnly True if kernel yielding on IO objects is disabled in favor of forced TPS.
|
|
* Do note that the throughput of a tick will differ per platform. Accept rate,
|
|
* throughput, etc may need tweaking, if you wish to drive an IIOProcessor using
|
|
* a timer or the manual tick functions.
|
|
* @param pQueue
|
|
* @return
|
|
*/
|
|
AUKN_SYM AuSPtr<IIOProcessor> NewIOProcessor(bool bTickOnly, const AuSPtr<Loop::ILoopQueue> &pQueue);
|
|
|
|
/**
|
|
* @brief Creates an IOProcessor to execute tasks on the loop queue of a given AuAsync thread id
|
|
* @param bTickOnly True if kernel yielding on IO objects is disabled in favor of forced TPS.
|
|
* Do note that the throughput of a tick will differ per platform. Accept rate,
|
|
* throughput, etc may need tweaking, if you wish to drive an IIOProcessor using
|
|
* a timer or the manual tick functions.
|
|
* @param pQueue
|
|
* @return
|
|
*/
|
|
AUKN_SYM AuSPtr<IIOProcessor> NewIOProcessorOnThread(bool bTickOnly, Async::WorkerPId_t id);
|
|
|
|
AUKN_SYM AuSPtr<IIOProcessor> NewIOProcessorNoQueue(bool bTickOnly);
|
|
} |