# StateControl2 **Repository Path**: Jimmy73820916/statecontrol2 ## Basic Information - **Project Name**: StateControl2 - **Description**: 使用QT开发的状态控制平台, - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-10-26 - **Last Updated**: 2025-11-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # StateControl #### 介绍 基于QT的状态控制引擎 #### 开发环境 QT 5.15.2 luajit2 #### 使用说明 #### 创建项目 #### 单元属性     单元 是 StateControl 的操作对象,unit有如下属性 - ID:唯一的标识每个单元,只能使用英文字符,数字加 __表示,最大长度64。 - Name: 便于记忆的名字 - Category:单元所在分类 - InputSignalCondition:接收输入时发信号条件。 - Unsupport: 不支持输入。 - None:不发信号 - Any: 只要有触发就发信号 - StateChange:状态改变时发信号 - StateChangeAndNotEmpty:状态改变并且值非空发信号; 空的集合为 0,false,"",{},[] - BehaviorType:行为类型。 - EqualInput :等于输入或信号值 - ReversalOnNotEmpty 收到非空时反转,0->1,!0->0,true<->false; 不支持其他数据类型 - ReversalOnSetSignal 收到置位信号时反转 - Extension 使用脚本或DLL实现行为 - Delegate 行为委托给其他单元实现 - TriggerSignalCondition:触发时发信号条件。 * Unsupport: 不支持触发。 * None:不发信号 * Any: 只要有触发就发信号 * StateChange:状态改变时发信号 * StateChangeAndNotEmpty:状态改变并且值非空发信号; 空的集合为 0,false,"",{},[] * EnableOutput:是否允许输出(对于允许输入的单元一定允许输出) - Implementation:实现的文件名。后缀是.dll,.so 或 .lua。所有实现的根目录是项目文件所在目录下的 Implementation 目录,指定了 Implementation 后,在实现文件中一般要实现5个函数 - [ID]OnAction 必须,单元收到触发信号后执行的函数 - [ID]OnInitialize 可选,如果单元的初始值需要动态设置则实现 - [ID]OnTime 可选如果单元需要支持计时器则实现 - [ID]Backup 可选,保存快照时存储单元的一些额外状态 - [ID]Restore 可选,加载快照时恢复单元保存的额外状态 - [ID]Pause 可选,收到暂停命令时执行的操作 * [ID]Resume可选,收到继续命令时执行的操作 - Implementation 也可以是其他单元的ID,表示当前单元的行为委托给指定的单元实现,在被指定的单元称作受托单元。如果Implementation为空对于UnitType是Input的单元在状态改变后会按SignalCondition设置执行发信号的行为 - State: 单元的当前状态 - InitialState:单元的初始状态,如果初始状态需要动态指定,则必须实现on_initialize函数 - Trigger:触发器单元,触发器单元发信号后,当前单元执行[Action]OnAction。 - Description 单元的描述性信息 #### 接口函数参数说明     StateControl 支持 2种类型的扩展 Lua脚本和C++扩展(dll 或 so),调用参数和返回值都是json格式数据,下面介绍时以 %d表示json数字,%s表示json字符串,%r 表示任意合法的json值,%o 表示json对象,%a 表示json数组 - [ID]OnInitialize:调用参数:无,返回值:有 - 注:OnInitialize 只能启动计数器,受托单元在OnInitialize中可以初始化委托单元。但如果多个单元的初始化有依赖的情况则结果不确定,系统只保证受托单元最后初始化。 - [ID]OnAction:调用参数:有,返回值:有 - 注1:调用参数说明 {“_trigger":%a,"_t1":%r,"_t2":%r,..."_state":%r","__timestamp":%d,"_d1":%r,"_d2":%r,...} _trigger表示所有的触发单元列表,_t1,_t2,-tn表示触发单元的ID状态,_d1,_d2,-dn表示委托单元。“_trigger" 正常情况下应该是一个单元,在某些情况下(系统忙或单元阻塞),调度系统会把积攒的事件合并,形成_trigger列表。 - 注2:如果在StateControlEditor的单元编辑器中选中所有订阅单元作为调用参数,调用参数中还会有所有订阅单元的id和state - [ID]OnTime 调用参数:有,返回值:有 - 注:调用参数说明 {“_tags":%a,..."_state":%r","__timestamp":%d,"_d1":%r,"_d2":%r,...},"_tags" 为计时器事件列表,_d1,_d2,-dn表示委托单元。 - [ID]Backup 调用参数:无,返回值:有 - Backup用于在创建快照时备份单元的私有信息 - [ID]Restore 调用参数:有,返回值:无 - Restore用于在加载快照时恢复单元的私有信息 - [ID]Pause 调用参数:无,返回值:无 - 收到 pause 命令时执行的操作(如果系统中没有调用第三方库的话基本可忽略) - [ID]Resume 调用参数:无,返回值:无 - 收到resume 命令时执行的操作(如果系统中没有调用第三方库的话基本可忽略) - 返回值说明: - Lua 脚本返回 Nil 或 DLL,SO 返回的 rapidjson::Document 为 NULL 表示 忽略本次调用 - Lua 脚本返回 布尔,数字,数组或无法表示为json对象的字符串 或 DLL,SO 返回的 rapidjson::Document 为布尔,数字,字符串 ,数组则直接赋值给单元 - Lua 脚本返回 可以表示为json对象的字符串 或 DLL,SO 返回的 rapidjson::Document 为对象时如果key中不包含"_state","_start_timer","_stop_timer",对于受托单元key中没有任何委托单元的id,则将该对象直接复制给单元,如果包含上述的任何一个key则只只将"_state"的内容复制给单元,如无"_state"则不给单元赋值。 - 计时器描述 - {"_start_timer":{"_tag":%s,"_times":%d,"_interval":%d},...},返回并启动计时器 "_tag" 计时器标签,"_times" 调用次数,-1不限制次数,"_interval"调用间隔时间(毫秒)。 - {"_start_timer":[{"_tag":%s,"_times":%d,"_interval":%d},{"_tag":%s,"_times":%d,"_interval":%d}],...},返回并启动多个计时器 - {...,"_start_timer":"%s"},返回并启动计时器"%s",_interval为1秒,times = -1 - {...,"_stop_timer":"%s"},返回并关闭计时器"%s" * {...,"_stop_timer":["%s",...]},返回并关闭多个计时器 * {...,"_stop_timer":“_all”} 返回并停止所有计时器 * 多次创建一个同名计时器,后面创建的参数会覆盖前面的。 * 删除一个不存在的计时器没有任何副作用。 #### 通讯协议     StateRuleServer 运行后与客户端使用Tcp协议进行通讯。编码为uft8,命令如下 - 暂停项目: - 发送:{"action":"pause"} - 回复:无 - 继续项目: - 发送:{"action":"resume"} - 回复:无 - 获取项目状态: - 发送:{"action":"game_state"} - 回复:{"action":"game_state","state":“%s”} - 注册为监视器(可以收到所有单元状态变化信息和任务信息): - 发送:{"action":"register_monitor"}   - 回复:无 - 发送广播: - 发送:{"action":"boardcast",...} - 由StateControllor无条件转发给所有Clients - 获取所有单元状态: - 发送:{"action":"query_all"} - 回复:{"id":%s,state":%r} - 创建快照: - 发送:{"action":"create_snapshoot","name":"%s"} - 回复:{"action":"create_snapshoot","name":"%s","result":"succeed|failed"[,"reason":%s]} - 加载快照: - 发送:{"action":"load_snapshoot","name":"%s"} - 回复:{"action":"load_snapshoot","name":"%s","result":"succeed|failed"[,"reason":%s]} - 重置项目: - 发送:{"action":"reset"} - 应答一组{"id":%s,”state":%r}命令集合,将所有值不等于默认值的单元复位 - 查询单元状态: - 发送:{"action":"query","id":%s} - 回复:{"action":"answer_query","id":%s,state":%r} - 单元状态变化: - 发送:{"id":"%s","state":%d} - 回复(0个或多个):{"id":"value_changed_unit_name",value":%r} * 心跳: * 发送:{"action":"ping"} * 应答:{"action":"pong"} * 查询任务事件:查询StateControllor 总线程数,活跃线程数,和任务队列中的任务数,"has_total":true要求返回总线程数 * 发送:{"action":"query_event"[,"has_total":false]} * 应答:{"action":"event_state","queue":%d,"active":%d[,"total":%d]} #### 联系作者     作者:Jimmy Song     如果在使用过程中你有什么想法,建议或问题,欢迎联系我,我会乐于与你探讨     邮箱: 52333676@qq.com