#ifndef _KERNEL_h
#define _KERNEL_h
#include "Task.h"
#include "EventListener.h"
#define KERNEL_MAX_HANDLES 256
#define KERNEL_MAX_TASKS 32
#define KERNEL_MAX_EVENT_SUBSCRIPTIONS 64
typedef void (*kernel_handle_destructor_t)(kernel_handle_t, void*);
struct KernelHandle;
struct KernelTask;
struct KernelEventSubscription;
///
/// WatchOS kernel providing the supervisor that makes it all go
///
class Kernel
{
private:
///
/// Holds the accounting of all handles the kernel has allocated
///
KernelHandle* m_handle[KERNEL_MAX_HANDLES];
///
/// Id of the next handle to allocate
///
int m_next_handle = 1;
///
/// Holds a reference and metadata for every task registered with the kernel
///
KernelTask* m_task[KERNEL_MAX_TASKS];
///
/// Holds a reference and metadata for every event subscription
///
KernelEventSubscription* m_event_subscription[KERNEL_MAX_EVENT_SUBSCRIPTIONS];
///
/// Perform the actual actions to free a handle
///
///
/// Calls the destructor (if set), and removes it from the kernel's internal tracking
///
/// handle to free
void freeHandle(kernel_handle_t handle);
public:
Kernel();
///
/// Initialize the kernel on first boot and notify tasks to do the same
///
void initialize();
///
/// Have all tasks perform startup after booting
///
void start();
///
/// Notify all tasks and the kernel to prepare for deep sleep by saving any state
/// required to persistent storage.
///
void suspend();
///
/// Create a new kernel handle pointing to an object
///
/// type of the handle, one of WATCHOS_HANDLE_TYPE_ consts
/// pointer to the object this handle references
/// function to call when this handle has released all references
/// specify a 'well_known' value this pointer can be fetched by
/// a handle which can be used to fetch or release this object
kernel_handle_t allocHandle(byte type, void* object, kernel_handle_destructor_t destructor = nullptr, uint32_t well_known = 0);
///
/// Fetch the object referenced by this handle
///
/// handle to fetch
/// a pointer to the object the handle references
void* getHandle(kernel_handle_t handle);
///
/// Increase the reference count of a handle
///
/// handle to increase reference count on
void useHandle(kernel_handle_t handle);
///
/// Decrease the reference count of a handle
///
/// handle to decrease reference count on
void releaseHandle(kernel_handle_t handle);
///
/// Fetch the handle associated with a "well known" handle
///
/// a well known handle we're trying to locate
/// the kernel handle of the well known object
kernel_handle_t getHandleForWellKnown(well_known_handle_t handle);
///
/// Register a new task with the kernel
///
/// task implementation to register
/// optionally, register this as a well known object
/// the handle of the registered task
kernel_handle_t registerTask(Task* task, well_known_handle_t wk_handle = WATCHOS_HANDLE_NULL);
///
/// Unregisters a task with the kernel
///
/// task implementation to unregister
void unregisterTask(Task* task);
///
/// Push an event to all relevant subscribers
///
///
/// This will look through all subscriptions and see which subscriptions' masks are
/// set to receive events of this source/type, and push the event through to the
/// applicable listeners.
///
/// handle of the sender
/// id of the event; what the event means
/// event-defined data
/// event-defined data
void pushEvent(well_known_handle_t source, uint16_t event, byte param1, byte param2);
///
/// Subscribe a listener to an event
///
/// listener that should receive events
/// a bitmask of the event sources that we want to receive
/// a bitmask of the event types that we want to receive
/// a handle to the subscription
kernel_handle_t subscribeEvent(EventListener* listener, well_known_handle_t source_mask, uint16_t event_mask);
///
/// Remove an event subscription
///
/// the subscription to remove
void unsubscribeEvent(KernelEventSubscription* subscription);
///
/// Have the kernel and any runnable tasks do processing
///
void tick();
};
#endif