You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "XTask.h"
#include "XDefine.h"
#include "XLua.h"
#include "ISubCoreCallback.h"
#include "XGlobal.h"
#include <string>
#include <QDateTime>
XTask XTask::instance;
XTask::XTask()
: lua(new XLua)
, id(0)
, pCallback(nullptr)
, isLoad(false)
, isEnd(false)
, stepIndex(0)
, startTime(0)
, totalUseTime(0)
, currentStepTime(0)
, stepUseTime(0)
{
}
XTask::~XTask() {
_SAFE_SELF_RELEASE_(lua);
pCallback = nullptr;
}
XTask& XTask::getInstance() {
return instance;
}
bool XTask::init(unsigned int taskId, const char* path) {
if (!isLoad) {
connect(this, &XTask::notifyExec, this, &XTask::onExec, Qt::QueuedConnection);
connect(this, &XTask::notifyGetNextStepCondition, this, &XTask::onGetNextStepCondition, Qt::QueuedConnection);
connect(&condTrigger, &XTaskConditionTrigger::notifyTrigger, this, &XTask::notifyTaskTrigger, Qt::QueuedConnection);
connect(this, &XTask::notifyEnd, this, &XTask::onEnd, Qt::QueuedConnection);
_CHECK_VALUE_RETURN_BOOL_(nullptr != path);
bool ret = lua->init();
_CHECK_VALUE_RETURN_BOOL_(ret);
std::string filePath = path;
filePath += "/";
filePath += _TASK_EXEC_SCRIPT_NAME_;
ret = lua->loadFile(filePath.c_str());
_CHECK_VALUE_RETURN_BOOL_(ret);
isLoad = true;
id = taskId;
}
funName = _TASK_EXEC_SCRIPT_RUN_NAME_;
isEnd = false;
emit notifyExec();
return true;
}
void XTask::release() {
id = 0;
isLoad = false;
isEnd = true;
lua->release();
lua = nullptr;
}
void XTask::onTaskEventCheck(const char* name, const char* value, const char* value2/* = nullptr*/) {
if (nullptr == name || nullptr == value)
return;
if (!isLoad || isEnd)
return;
taskCondition.onTaskEventCheck(QString(name), QString(value), value2);
}
void XTask::onExec() {
if (!isLoad)
return;
if (isEnd)
return;
bool ret = false;
if (0 == stepIndex) {
// 说明是入口
// 获取开始时间
startTime = QDateTime::currentSecsSinceEpoch();
currentStepTime = startTime;
ret = lua->callFunction(funName.c_str(), RET_VALUE_INDEX_MAX - 1, this);
}
else
{
// 非入口
qint64 startStepTime = QDateTime::currentSecsSinceEpoch();
stepUseTime = startStepTime - currentStepTime;
currentStepTime = startStepTime;
totalUseTime += stepUseTime;
ret = lua->callFunction(funName.c_str(), RET_VALUE_INDEX_MAX - 1, this);
}
if (!ret) {
error(ISubCoreCallback::ERR_T_TASK_EXEC, QStringLiteral("任务步骤:执行脚本调用函数错误"), funName.c_str());
return;
}
// 步骤加1
++stepIndex;
}
void XTask::onGetNextStepCondition() {
if (isEnd)
return;
assert(!triggerConditionFunName.empty());
taskCondition.reset();
bool ret = lua->callFunction(triggerConditionFunName.c_str(), 1, &taskCondition);
if (!ret) {
error(ISubCoreCallback::ERR_T_TASK_SCRIPT, QStringLiteral("获取触发条件值失败"), triggerConditionFunName.c_str());
return;
}
taskCondition.buildConditions();
taskCondition.begin(&condTrigger);
}
void XTask::notifyTaskTrigger(const QString& funName) {
this->funName = funName.toStdString();
emit notifyExec();
}
void XTask::onEnd() {
if (nullptr != pCallback)
pCallback->onTaskEnd(id, 0);
}
unsigned int XTask::pushParam(IVariantProcessor* proc) {
if (nullptr == proc)
return 0;
// 如果步骤0说明为main
if (0 == stepIndex)
return 0;
proc->process(typeid(stepIndex), &stepIndex);
static std::string tmpStepName;
tmpStepName = stepName.toStdString();
const char* name = tmpStepName.c_str();
proc->process(typeid(name), &name);
proc->process(typeid(totalUseTime), &totalUseTime);
proc->process(typeid(stepUseTime), &stepUseTime);
return 4;
}
void XTask::getReturnValues(unsigned int count, IVariantProcessor* proc) {
if (nullptr == proc)
return;
char* ptr = nullptr;
// 下一个步骤函数名
proc->getValue(count, RET_VALUE_INDEX_TRIGGER_CONDITION_FUNNAME, typeid(char*), &ptr);
assert(nullptr != ptr);
triggerConditionFunName = ptr;
// 当前步骤名
ptr = nullptr;
proc->getValue(count, RET_VALUE_INDEX_CURRENT_STEP_NAME, typeid(char*), &ptr);
if (nullptr != ptr) {
stepName = ptr;
ptr = nullptr;
}
else
{
stepName = QStringLiteral("数字指挥员系统");
}
// 资源图片
proc->getValue(count, RET_VALUE_INDEX_RESOURCES_IMAGE, typeid(char*), &ptr);
if (nullptr != ptr) {
currentRetData.img = ptr;
ptr = nullptr;
}
// 资源文本
proc->getValue(count, RET_VALUE_INDEX_RESOURCES_TEXT, typeid(char*), &ptr);
if (nullptr != ptr) {
currentRetData.txt = ptr;
ptr = nullptr;
}
// 资源声音
proc->getValue(count, RET_VALUE_INDEX_RESOURCES_SOUND, typeid(char*), &ptr);
if (nullptr != ptr)
currentRetData.sound = ptr;
if (nullptr != pCallback) {
pCallback->openTaskDlg(stepName.toStdString().c_str(),
currentRetData.img.empty() ? nullptr : currentRetData.img.c_str(),
currentRetData.txt.empty() ? nullptr : currentRetData.txt.c_str(),
currentRetData.sound.empty() ? nullptr : currentRetData.sound.c_str());
}
const static std::string endFunName("__end__");
if (0 != triggerConditionFunName.compare(endFunName)) {
emit notifyGetNextStepCondition();
}
else
{
isEnd = true;
emit notifyEnd();
}
}
void XTask::error(unsigned int type, const QString& title, const char* funName) {
QString errText = QStringLiteral("%1当前步骤%2函数%3。");
errText = errText.arg(title).arg(stepName).arg(funName);
XGlobal::getInstance().onError(type, errText);
}