#ifndef DP_COMMON_H #define DP_COMMON_H #include #include #include #include "dp_types.h" #include "log.h" #ifdef __cplusplus extern "C" { #endif #define dp_fatal(...) log_fatal(__VA_ARGS__) typedef pid_t doomid_t; // unique id for each doom instance typedef u16 dmt_t; // for DP_MessageType values typedef enum DP_MessageType { DP_MT_Invalid, DP_MT_DoomState, // dooms can publish their state (MsgDoomState) DP_MT_DoomFrame, // doom framebuffer data DP_MT_Command, // DP_DoomCommand message to a specific doom instance DP_MT_McstCommand, // DP_DoomCmannd multicast message to all dooms DP_MT_Inputs, // controller publishes input state for dooms to consume DP_MT_COUNT } DP_MessageType; typedef enum DP_DoomState { DP_DS_Unknown, DP_DS_Ready, DP_DS_Running, DP_DS_Quitting, DP_DS_COUNT, } DP_DoomState; typedef enum DP_DoomCommand { DP_DC_Noop, DP_DC_RunDoom, DP_DC_QuitDoom, DP_DC_COUNT, } DP_DoomCommand; typedef struct { dmt_t msgType; } MessageBase; typedef struct __attribute__((packed, aligned(4))) { MessageBase head; doomid_t doomId; DP_DoomState doomState; } MsgDoomState; typedef struct __attribute__((packed, aligned(4))) { MessageBase head; u8 frame[320 * 200]; } MsgDoomFrame; typedef struct __attribute__((packed, aligned(4))) { MessageBase head; doomid_t doomId; DP_DoomCommand cmd; } MsgCommand; typedef struct __attribute__((packed, aligned(4))) { MessageBase head; DP_DoomCommand cmd; } MsgMcstCommand; typedef struct __attribute__((packed, aligned(4))) { MessageBase head; } MsgInputs; void dp_errno_fatal(const char *const msg); void dp_nng_fatal(const char *const msg, int rv); void dp_nng_init_limits(int ncpu_max, int pool_thread_limit_max, int resolv_thread_limit); inline bool dp_nng_is_timeout(int res) { return res == NNG_ETIMEDOUT || res == NNG_EAGAIN; } static const char *const CtrlUrl = "ipc://666_ctrl.socket"; // controller publishes here static const char *const DoomUrl = "ipc://666_doom.socket"; // dooms publish here nng_socket make_ctrl_pub(const char *url); nng_socket make_ctrl_sub(const char *url); nng_socket make_doom_pub(const char *url); nng_socket make_doom_sub(const char *url); int dp_recv_new_msg(nng_socket sock, nng_msg **msg_ptr); int dp_recv_new_msg_nonblock(nng_socket sock, nng_msg **msg_ptr); int dp_recv_new_msg_flags(nng_socket sock, nng_msg **msg_ptr, int flags); inline void *dp_nng_msg_body_if_size_ge(nng_msg *msg, size_t size, bool isFatal) { if (nng_msg_len(msg) >= size) return nng_msg_body(msg); if (isFatal) dp_fatal("message body too short"); return NULL; } // Size checked cast of message body to type, fatal version #define DP_NNG_BODY_AS(msg, ToType) (ToType *) dp_nng_msg_body_if_size_ge(msg, sizeof(ToType), true) // Size checked cast of message body to type, non-fatal version #define DP_NNG_BODY_AS_NF(msg, ToType) (ToType *) dp_nng_msg_body_if_size_ge(msg, sizeof(ToType), false) extern const char *const DP_DoomState_Strings[]; static inline const char *doomstate_to_string(DP_DoomState ds) { return DP_DoomState_Strings[ds]; } #ifdef __cplusplus } #endif #endif /* DP_COMMON_H */