HCoreBase/src/HProtocolBind.c
2025-11-05 18:28:37 +08:00

263 lines
7.3 KiB
C

#include "HProtocolBind.h"
#include "HDLog.h"
#include <string.h>
#ifndef LogD
#define LogD(...)
#endif
#define CREATE_INDEX(id, index) ((id << 8) | index)
#define GET_ID(index) ((index >> 8) & 0xFF)
#define GET_INDEX(index) (index & 0xFF)
enum eEnableStatus
{
kNotEnable, ///< 未使能
kWaitEnable, ///< 等待使能
kEnable, ///< 使能
kCallEnable, ///< 回调时使能, 需要延迟使能
};
struct __attribute__((packed)) BindInfo
{
uint32_t enable : 1; ///< 绑定使能
uint32_t curr : 1; ///< 当前绑定
uint32_t isCallAdd : 1; ///< 在回调的时候添加
uint32_t useLen : 8; ///< 使用长度, 减少扫描次数
uint32_t len : 8; ///< 绑定个数
HProtocolBindInfo *binds; ///< 绑定
};
static struct BindInfo sBindRegisters[HPROTOCOL_BIND_MAX];
static void FreeItem(uint8_t id, HProtocolBind_t index) {
if (sBindRegisters[id].enable) {
--sBindRegisters[id].useLen;
}
memset(&sBindRegisters[id].binds[index], 0, sizeof(HProtocolBindInfo));
}
static void ResetEnable(uint8_t id) {
if (sBindRegisters[id].isCallAdd == 0) {
return ;
}
sBindRegisters[id].isCallAdd = 0;
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
if (sBindRegisters[id].binds[i].enable == kCallEnable) {
sBindRegisters[id].binds[i].enable = kEnable;
}
}
}
uint8_t HProtocolBindRegister(uint8_t id, HProtocolBindInfo *info, uint8_t infoLen) {
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return 0;
}
if (sBindRegisters[id].enable == 1) {
LogD("id[%d] already register", id);
return 0;
}
sBindRegisters[id].binds = info;
sBindRegisters[id].len = infoLen;
sBindRegisters[id].enable = 1;
return 1;
}
HProtocolBind_t HProtocolBindAddTask(HProtocolBindId_t id, HProtocolBindFunc_t func, HProtocolBindCallback callback, uint8_t keepAlive) {
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return HPROTOCOL_BIND_INVALID;
}
if (sBindRegisters[id].enable == 0) {
LogD("not enable, id[%d]", id);
return HPROTOCOL_BIND_INVALID;
}
if (callback == NULL) {
LogD("callback is null, id[%d]", id);
return HPROTOCOL_BIND_INVALID;
}
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
if (sBindRegisters[id].binds[i].enable) {
continue;
}
// 防中断导致数据重叠
sBindRegisters[id].binds[i].enable = kWaitEnable;
if (sBindRegisters[id].binds[i].enable != 1) {
continue;
}
++sBindRegisters[id].useLen;
sBindRegisters[id].binds[i].enable = kEnable;
sBindRegisters[id].binds[i].delayMs = HPROTOCOL_BIND_TIMEOUT;
sBindRegisters[id].binds[i].isTimeout = 0;
sBindRegisters[id].binds[i].func = func;
sBindRegisters[id].binds[i].lastTime = HDLogGetTime();
sBindRegisters[id].binds[i].callback = callback;
sBindRegisters[id].binds[i].keepAlive = keepAlive;
// 当前在回调, 需要延迟使能
if (sBindRegisters[id].curr) {
sBindRegisters[id].binds[i].enable = kCallEnable;
sBindRegisters[id].isCallAdd = 1;
}
return CREATE_INDEX(id, i);
}
LogD("bind full, id[%d], len[%d]", id, sBindRegisters[id].len);
return HPROTOCOL_BIND_INVALID;
}
void HProtocolBindSetTimeout(HProtocolBind_t index, uint32_t delayMs)
{
const uint8_t id = GET_ID(index);
index = GET_INDEX(index);
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return ;
}
if (index < 0 || index >= sBindRegisters[id].len) {
LogD("error index[%d], len[%d]", index, sBindRegisters[id].len);
return ;
}
sBindRegisters[id].binds[index].delayMs = delayMs;
}
void HProtocolBindRemoveTask(HProtocolBind_t index) {
const uint8_t id = GET_ID(index);
index = GET_INDEX(index);
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return ;
}
if (index < 0 || index >= sBindRegisters[id].len) {
LogD("error index[%d], len[%d]", index, sBindRegisters[id].len);
return ;
}
FreeItem(id, index);
}
uint8_t HProtocolBindIsTimeout(HProtocolBind_t index) {
const uint8_t id = GET_ID(index);
index = GET_INDEX(index);
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return 0;
}
if (index < 0 || index >= sBindRegisters[id].len) {
LogD("error index[%d], len[%d]", index, sBindRegisters[id].len);
return 0;
}
return sBindRegisters[id].binds[index].isTimeout;
}
void HProtocolBindUpdateData(HProtocolBindId_t id, HProtocolBindFunc_t func, void* data, uint16_t len) {
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return ;
}
if (sBindRegisters[id].enable == 0) {
LogD("not enable, id[%d]", id);
return ;
}
// 减少扫描次数
if (sBindRegisters[id].useLen == 0) {
return ;
}
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
if (sBindRegisters[id].binds[i].enable == kNotEnable || sBindRegisters[id].binds[i].enable == kCallEnable) {
continue;
}
if (sBindRegisters[id].binds[i].func != func) {
continue;
}
if (sBindRegisters[id].binds[i].isTimeout) {
continue;
}
// 可能是同一个功能码绑定多个回调
if (sBindRegisters[id].binds[i].callback) {
sBindRegisters[id].curr = 1;
sBindRegisters[id].binds[i].callback(CREATE_INDEX(id, i), (uint8_t*)data, len);
sBindRegisters[id].curr = 0;
}
// 回调后立即释放
if (sBindRegisters[id].binds[i].keepAlive == 0) {
FreeItem(id, i);
}
}
}
void HProtocolBindRun(HProtocolBindId_t id)
{
if (id >= HPROTOCOL_BIND_MAX) {
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
return ;
}
if (sBindRegisters[id].enable == 0) {
LogD("not enable, id[%d]", id);
return ;
}
// 减少扫描次数
if (sBindRegisters[id].useLen == 0) {
return ;
}
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
if (sBindRegisters[id].binds[i].enable == kNotEnable || sBindRegisters[id].binds[i].enable == kCallEnable) {
continue;
}
if (sBindRegisters[id].binds[i].keepAlive) {
continue;
}
if (sBindRegisters[id].binds[i].isTimeout) {
continue;
}
if (HDLogGetTime() - sBindRegisters[id].binds[i].lastTime < sBindRegisters[id].binds[i].delayMs) {
continue;
}
sBindRegisters[id].binds[i].isTimeout = 1;
// 可能是同一个功能码绑定多个回调
if (sBindRegisters[id].binds[i].callback) {
sBindRegisters[id].curr = 1;
sBindRegisters[id].binds[i].callback(CREATE_INDEX(id, i), NULL, 0);
sBindRegisters[id].curr = 0;
}
// 回调后立即释放
FreeItem(id, i);
}
ResetEnable(id);
}