SimsWorld/ComponentBasic/BehaviorPerform.h

773 lines
20 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "componentbasic.h"
#include <messagebasic.h>
#include <QJsonObject>
#include <QJSEngine>
class MessageLoader;
class CompareDelegate;
class ConvertDelegate;
class ExecuteDelegate;
class LogicalNode;
/// <summary>
/// 通用数据类型
/// </summary>
struct COMPONENTBASIC_EXPORT GeneralData : public TopicData {
QJsonObject _element_bind;
QString topicString() const override;
std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
// ==================================================================================
/// <summary>
/// 行为树实例化节点
/// </summary>
class COMPONENTBASIC_EXPORT MapKernel :
public QObject, virtual public Serializable,
public std::enable_shared_from_this<MapKernel> {
Q_OBJECT
private:
/// <summary>
/// 绑定载入器
/// </summary>
std::shared_ptr<MessageLoader> _bind_loader;
QJSEngine _core_engine;
/// <summary>
/// {Topicdefault-value}
/// </summary>
QHash<QString, std::shared_ptr<TopicData>> _variable_types;
/// <summary>
/// 比较器
/// </summary>
QHash<QString, std::shared_ptr<CompareDelegate>> _compare_types;
/// <summary>
/// 转换器
/// </summary>
QHash<QString, std::shared_ptr<ConvertDelegate>> _convert_types;
/// <summary>
/// 执行器
/// </summary>
QHash<QString, std::shared_ptr<ExecuteDelegate>> _execute_types;
/// <summary>
/// 所有可用的节点类型
/// </summary>
QHash<QString, std::shared_ptr<LogicalNode>> _logicalnode_types;
signals:
/// <summary>
/// 比较器类型列表变更
/// </summary>
void compareTypeListChanged();
/// <summary>
/// 转换器类型列表变更
/// </summary>
void convertTypeListChanged();
public:
MapKernel(std::shared_ptr<MessageLoader> ins);
virtual ~MapKernel() = default;
void initial();
QJSEngine& bindEngine();
// 数据类型管理 ======================================================
/// <summary>
/// 注册数据类型
/// </summary>
/// <param name="init"></param>
virtual void registData(std::shared_ptr<TopicData> init);
/// <summary>
/// 获取所有可用数据类型
/// </summary>
/// <returns></returns>
virtual QList<QString> dataTypes() const;
/// <summary>
/// 获取指定topic的数据类型
/// </summary>
/// <param name="topic"></param>
/// <returns></returns>
virtual std::shared_ptr<TopicData> getData(const QString& topic) const;
// 逻辑树类型管理 ====================================================
/// <summary>
/// 注册逻辑节点
/// </summary>
/// <param name="ins"></param>
virtual void registNode(std::shared_ptr<LogicalNode> ins);
/// <summary>
/// 执行器类型名称
/// </summary>
/// <returns></returns>
virtual QList<QString> nodeTypes() const;
/// <summary>
/// 获取指定类型的执行器节点
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
virtual std::shared_ptr<LogicalNode> getNode(const QString& name) const;
// 比较器类型管理 ======================================================
/// <summary>
/// 注册比较器
/// </summary>
/// <param name="ins"></param>
virtual void registCompare(std::shared_ptr<CompareDelegate> ins);
/// <summary>
/// 获取比较器类型
/// </summary>
/// <returns></returns>
virtual QList<QString> compareTypes() const;
/// <summary>
/// 获取比较器单例实例
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
virtual std::shared_ptr<CompareDelegate> getCompare(const QString& name) const;
// 转换器类型管理 ======================================================
/// <summary>
/// 注册转换器
/// </summary>
/// <param name="ins"></param>
virtual void registConvert(std::shared_ptr<ConvertDelegate> ins);
/// <summary>
/// 转换器类型名称
/// </summary>
/// <returns></returns>
virtual QList<QString> convertTypes() const;
/// <summary>
/// 获取指定类型的转换器
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
virtual std::shared_ptr<ConvertDelegate> getConvert(const QString& name) const;
// 执行节点类型管理 ====================================================
/// <summary>
/// 注册拓展执行器
/// </summary>
/// <param name="ins"></param>
virtual void registExecute(std::shared_ptr<ExecuteDelegate> ins);
/// <summary>
/// 执行器类型名称
/// </summary>
/// <returns></returns>
virtual QList<QString> executeTypes() const;
/// <summary>
/// 获取指定类型的执行器节点
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
virtual std::shared_ptr<ExecuteDelegate> getExecute(const QString& name) const;
// 通过 Serializable 继承
std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 比较关系实例
/// </summary>
class COMPONENTBASIC_EXPORT CompareDelegate : public Serializable {
private:
QJSEngine& _script_engine;
QString _function_name;
public:
CompareDelegate(QJSEngine& bind_engine, const QString& func);
QString name() const;
bool compare(std::shared_ptr<TopicData> vleft, std::shared_ptr<TopicData> vright);
std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 数据转换实例
/// </summary>
class COMPONENTBASIC_EXPORT ConvertDelegate : public Serializable {
public:
typedef QString DATA_TOPIC_STRING;
/// <summary>
/// 构建转换器
/// </summary>
/// <param name="host">数据类型管理核心</param>
/// <param name="bind_engine"></param>
/// <param name="func"></param>
ConvertDelegate(std::shared_ptr<MapKernel> host, QJSEngine& bind_engine, const QString& func);
/// <summary>
/// 转换器名称JS函数名
/// </summary>
/// <returns></returns>
QString name() const;
/// <summary>
/// 输入变量类型绑定表
/// </summary>
/// <returns>list{pair{类型名称,绑定输入变量名}}</returns>
QList<std::pair<DATA_TOPIC_STRING, QString>> inputTable() const;
/// <summary>
/// 重置输入变量类型表
/// </summary>
/// <param name="table">list{pair{类型名称,绑定输入变量名}}</param>
void inputReset(const QList<std::pair<DATA_TOPIC_STRING, QString>>& table);
/// <summary>
/// 输入变量
/// </summary>
/// <returns>pair{类型名称,绑定输出变量名}</returns>
std::pair<DATA_TOPIC_STRING, QString> outputVariable() const;
/// <summary>
/// 重置输出变量类型名
/// </summary>
/// <param name="appoint"></param>
void outputReset(std::pair<DATA_TOPIC_STRING, QString> appoint);
/// <summary>
/// 执行转换
/// </summary>
/// <param name="input_variables">输入变量列表</param>
/// <returns></returns>
std::shared_ptr<TopicData> convert(const QList<std::shared_ptr<TopicData>>& input_variables);
std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
private:
std::shared_ptr<MapKernel> _host_bind;
QJSEngine& _script_engine;
QString _function_name;
QList<std::pair<DATA_TOPIC_STRING, QString>> _input_table;
std::pair<DATA_TOPIC_STRING, QString> _output_appoint;
};
/// <summary>
/// 执行结果
/// </summary>
enum class ExecuteResult {
UNDEFINED, // 未定义
SUCCESS, // 成功
FAILURE // 失败
};
/// <summary>
/// 执行代理
/// </summary>
class COMPONENTBASIC_EXPORT ExecuteDelegate : public Serializable {
public:
/// <summary>
/// 获取节点名称
/// </summary>
/// <returns></returns>
virtual QString typeName() const = 0;
/// <summary>
/// 声明输入变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> inputList() const = 0;
/// <summary>
/// 声明输出变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> outputList() const = 0;
/// <summary>
/// 重置内部状态
/// </summary>
virtual void reset() = 0;
/// <summary>
/// 执行逻辑节点
/// </summary>
/// <param name="core"></param>
/// <returns></returns>
virtual ExecuteResult execute() = 0;
};
/// <summary>
/// 逻辑节点类型
/// </summary>
enum class NodeKind {
MAPNODE, // 逻辑树节点
SEQUENCENODE, // 顺序节点
SELECTORNODE, // 选择节点
PARALLELNODE, // 并行节点
COMPARENODE, // 比较节点
ACTIONNODE, // 动作节点
MODIFYNODE, // 修饰节点
};
class BehaviorMapNode;
/// <summary>
/// 所有逻辑节点的基类
/// </summary>
class COMPONENTBASIC_EXPORT LogicalNode : virtual public Serializable, public std::enable_shared_from_this<LogicalNode> {
private:
int _node_id = 0;
NodeKind _node_type = NodeKind::ACTIONNODE;
std::shared_ptr<MapKernel> _bind_kernal;
std::weak_ptr<LogicalNode> _parent_bind;
QList<std::shared_ptr<LogicalNode>> _child_list;
/// <summary>
/// 重置父节点
/// </summary>
/// <param name="pnode"></param>
void _set_parent_node(std::weak_ptr<LogicalNode> pnode);
public:
LogicalNode(NodeKind t, std::shared_ptr<MapKernel> kernal);
virtual ~LogicalNode() = default;
/// <summary>
/// 获取节点类型
/// </summary>
/// <returns></returns>
NodeKind nodeKind() const;
/// <summary>
/// 节点深度
/// </summary>
/// <returns></returns>
int depth() const;
/// <summary>
/// 获取包含树图节点
/// </summary>
/// <returns></returns>
std::shared_ptr<BehaviorMapNode> bindMap() const;
std::shared_ptr<MapKernel> getKernal() const;
/// <summary>
/// 回退节点
/// </summary>
/// <returns></returns>
std::weak_ptr<LogicalNode> parent() const;
/// <summary>
/// 获取子节点列表
/// </summary>
/// <returns></returns>
virtual QList<std::shared_ptr<LogicalNode>> children() const;
/// <summary>
/// 添加子节点
/// </summary>
/// <param name="node"></param>
/// <param name="index"></param>
virtual void insert(std::shared_ptr<LogicalNode> node, int index = -1);
/// <summary>
/// 移除子节点
/// </summary>
/// <param name="node"></param>
virtual void remove(std::shared_ptr<LogicalNode> node);
/// <summary>
/// 设置节点id
/// </summary>
/// <param name="unique_id"></param>
void setID(int unique_id);
/// <summary>
/// 提取节点id
/// </summary>
/// <returns></returns>
int getID() const;
/// <summary>
/// 实例化节点名称
/// </summary>
/// <returns></returns>
virtual QString rtName() const;
/// <summary>
/// 获取节点名称
/// </summary>
/// <returns></returns>
virtual QString typeName() const = 0;
/// <summary>
/// 声明输入变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> inputList() const = 0;
/// <summary>
/// 声明输出变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> outputList() const = 0;
/// <summary>
/// 重置内部状态
/// </summary>
virtual void reset() = 0;
/// <summary>
/// 获取执行入口节点
/// </summary>
/// <returns></returns>
virtual QList<std::shared_ptr<LogicalNode>> getForwards() const = 0;
/// <summary>
/// 下行节点执行状态回返填充
/// </summary>
/// <param name="node"></param>
/// <param name="ste"></param>
/// <returns>接续执行标志</returns>
virtual bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) = 0;
/// <summary>
/// 执行逻辑节点
/// </summary>
/// <param name="core"></param>
/// <returns></returns>
virtual ExecuteResult execute() = 0;
/// <summary>
/// 新建默认实例
/// </summary>
/// <returns></returns>
virtual std::shared_ptr<Serializable> newDefault() const = 0;
};
/// <summary>
/// 逻辑树节点输入输出类型
/// </summary>
enum class IO_TYPE {
INPUT, // 输入
OUTPUT, // 输出
INTERNAL// 内部变量
};
/// <summary>
/// 自定义行为树节点根节点实例
/// </summary>
class COMPONENTBASIC_EXPORT BehaviorMapNode : public LogicalNode {
private:
QString _map_name = u8"行为树节点";
/// <summary>
/// 地图变量表
/// </summary>
QHash<QString, std::pair<IO_TYPE, std::shared_ptr<TopicData>>> _variables;
ExecuteResult _state_value = ExecuteResult::FAILURE;
public:
BehaviorMapNode(std::shared_ptr<MapKernel> kernal);
/// <summary>
/// 设置变量如果类型错误会抛出UniException异常
/// 节点初始化时会按照配置注册默认值变量
/// </summary>
virtual void setVariable(const QString& key, IO_TYPE t, std::shared_ptr<TopicData> ins);
virtual QList<QString> inputVariableKeys() const;
virtual QList<QString> outputVariableKeys() const;
virtual QList<QString> internalVariableKeys() const;
virtual void removeVariable(const QString &key);
/// <summary>
/// 获取指定名称的数据变量
/// </summary>
/// <param name="key"></param>
/// <returns>如果不存在指定名称数据返回nullptr类型不确定</returns>
virtual std::shared_ptr<TopicData> getVariable(const QString& key) const;
/// <summary>
/// 设置行为树节点名称
/// </summary>
/// <param name="val"></param>
virtual void resetName(const QString& val);
/// <summary>
/// 重置执行状态
/// </summary>
void reset() override;
/// <summary>
/// 实例名称
/// </summary>
/// <returns></returns>
QString rtName() const override;
/// <summary>
/// 获取节点类型名称
/// </summary>
/// <returns></returns>
QString typeName() const override;
/// <summary>
/// 提取前置节点
/// </summary>
/// <returns></returns>
QList<std::shared_ptr<LogicalNode>> getForwards() const override;
/// <summary>
/// 填充状态
/// </summary>
/// <param name="node"></param>
/// <param name="ste"></param>
/// <returns></returns>
bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
/// <summary>
/// 执行状态
/// </summary>
/// <returns></returns>
ExecuteResult execute() override;
/// <summary>
/// 输入变量列表
/// </summary>
/// <returns></returns>
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
/// <summary>
/// 输出变量列表
/// </summary>
/// <returns></returns>
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
/// <summary>
/// 创建新实例
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
// 行为树节点 ======================================================
/// <summary>
/// 顺序节点
/// </summary>
class COMPONENTBASIC_EXPORT SequenceNode : public LogicalNode {
private:
QHash<int, ExecuteResult> _state_map;
public:
SequenceNode(std::shared_ptr<MapKernel> kernal);
QList<std::shared_ptr<LogicalNode>> getForwards() const override;
QString typeName() const override;
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
void reset() override;
ExecuteResult execute() override;
bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 选择节点
/// </summary>
class COMPONENTBASIC_EXPORT SelectorNode : public LogicalNode {
private:
QHash<int, ExecuteResult> _state_map;
public:
SelectorNode(std::shared_ptr<MapKernel> kernal);
QList<std::shared_ptr<LogicalNode>> getForwards() const override;
QString typeName() const override;
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
void reset() override;
ExecuteResult execute() override;
bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 并行节点
/// </summary>
class COMPONENTBASIC_EXPORT ParallelNode : public LogicalNode {
private:
QHash<int, ExecuteResult> _state_map;
public:
ParallelNode(std::shared_ptr<MapKernel> kernal);
QList<std::shared_ptr<LogicalNode>> getForwards() const override;
QString typeName() const override;
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
void reset() override;
ExecuteResult execute() override;
bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 比较节点
/// </summary>
class COMPONENTBASIC_EXPORT CompareNode : public LogicalNode {
private:
std::shared_ptr<CompareDelegate> _bind_delegate;
QHash<QString, std::shared_ptr<TopicData>> _data_map;
public:
CompareNode(std::shared_ptr<MapKernel> kernal);
QString delegateName() const;
void bindDelegate(std::shared_ptr<CompareDelegate> ins);
virtual QList<std::shared_ptr<LogicalNode>> getForwards() const override;
virtual QString rtName() const override;
QString typeName() const override;
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
virtual void insert(std::shared_ptr<LogicalNode> node, int index /*= -1*/) override;
void reset() override;
ExecuteResult execute() override;
virtual bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 执行节点
/// </summary>
class COMPONENTBASIC_EXPORT ExecuteNode : public LogicalNode {
private:
std::shared_ptr<ExecuteDelegate> _bind_delegate;
public:
ExecuteNode(std::shared_ptr<MapKernel> kernal);
QString delegateName() const;
void bindDelegate(std::shared_ptr<ExecuteDelegate> ins);
virtual QList<std::shared_ptr<LogicalNode>> getForwards() const override;
virtual QString rtName() const override;
QString typeName() const override;
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
virtual void insert(std::shared_ptr<LogicalNode> node, int index /*= -1*/) override;
void reset() override;
ExecuteResult execute() override;
virtual bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
/// <summary>
/// 修饰节点类型
/// </summary>
enum class ModifyType {
NONE,
ALWAYS_SUCCESS, // 永远成功
ALWAYS_FAILURE, // 永远失败
RESULT_INVENTER, // 结果翻转
};
class COMPONENTBASIC_EXPORT ModifiedNode : public LogicalNode {
private:
ModifyType _type_appoint = ModifyType::NONE;
ExecuteResult _result_store = ExecuteResult::UNDEFINED;
public:
ModifiedNode(std::shared_ptr<MapKernel> kernal);
ModifyType modifyType() const;
void resetModify(ModifyType t);
void insert(std::shared_ptr<LogicalNode> node, int index = -1) override;
virtual QString rtName() const override;
QString typeName() const override;
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
QList<std::shared_ptr<LogicalNode>> getForwards() const override;
bool fallback(std::shared_ptr<LogicalNode> node, ExecuteResult ste) override;
void reset() override;
ExecuteResult execute() override;
std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
// 行为节点 ====================================================================
/// <summary>
/// 行为树组件
/// </summary>
class COMPONENTBASIC_EXPORT BehaviorPerformPlugin :
public RespondRoute<
WsRespond<EntityInitialRequest, RespondDefault>,
WsRespond<EntityPreparedRequest, RespondDefault>,
WsRespond<SyncRequest, RespondDefault>,
WsRespond<DeduceRequest, RespondDefault>>,
public RequestRoute<>
{
private:
std::weak_ptr<WsEntity> _bind_entity;
public:
void mapReset(const QString& path);
// 通过 ProcList 继承
void execute(std::shared_ptr<const EntityInitialRequest> in, QList<std::shared_ptr<RespondDefault>>& out) override;
void execute(std::shared_ptr<const EntityPreparedRequest> in, QList<std::shared_ptr<RespondDefault>>& out) override;
void execute(std::shared_ptr<const SyncRequest> in, QList<std::shared_ptr<RespondDefault>>& out) override;
void execute(std::shared_ptr<const DeduceRequest> in, QList<std::shared_ptr<RespondDefault>>& out) override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
std::shared_ptr<Serializable> newDefault() const override;
void bindEntity(std::weak_ptr<WsEntity> host) override;
QString name() const override;
};