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.

353 lines
8.3 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 "XTaskCondition.h"
#include "IVariantProcessor.h"
#include "XCTool.h"
#include <QTimer>
XTaskCondition::XTaskCondition()
: condTrigger(nullptr)
{
}
XTaskCondition::~XTaskCondition() {
}
void XTaskCondition::getReturnValues(unsigned int count, IVariantProcessor* proc) {
proc->getValue(count, 1, typeid(IXLuaValueObject), this);
}
void XTaskCondition::buildConditions() {
// 先处理XConditionInfo
bool isExistsCondTimer = false;
for (auto& item : tmpItems) {
if(item.isProcess)
continue;
bool isInfo = false;
unsigned int type = TRIGGER_CONDITION_TYPE_NONE;
if (0 == COND_TYPE_NAME_TIMER.compare(item.name)) {
// 只允许有一个定时器,且开始第一个
if(isExistsCondTimer)
continue;
type = TRIGGER_CONDITION_TYPE_TIMER;
isExistsCondTimer = true;
}
else if (0 == COND_TYPE_NAME_EVENT_CHECK.compare(item.name)) {
type = TRIGGER_CONDITION_TYPE_OPER;
}
if(type == TRIGGER_CONDITION_TYPE_NONE)
continue;
XConditionInfo info;
info.groupIndex = item.groupIndex;
info.type = type;
info.value = item.index;
info.funName = item.value1.toString();
condInfos.push_back(info);
item.isProcess = true;
}
// 自定义排序
std::sort(condInfos.begin(), condInfos.end(),
[](const XConditionInfo& a, const XConditionInfo& b) {
return a.groupIndex < b.groupIndex; // 升序排序
}
);
// 处理MixedItem
for (auto& item : tmpItems) {
if (item.isProcess)
continue;
XConditionInfo* pInfo = getConditionInfo(item.groupIndex);
if (nullptr == pInfo) {
item.isProcess = true;
continue;
}
pInfo->items.push_back(item);
}
// 排序MixedItem
for (auto& info : condInfos) {
if (info.items.size() > 1) {
// 自定义排序
std::sort(info.items.begin(), info.items.end(), [](const MixedItem& a, const MixedItem& b) {
return a.index < b.index; // 升序排序
}
);
}
}
}
void XTaskCondition::begin(XTaskConditionTrigger* trigger) {
condTrigger = trigger;
// 开启所有的定时器
for (int i = 0; i < condInfos.size(); ++i) {
if (TRIGGER_CONDITION_TYPE_TIMER == condInfos[i].type) {
// 开启定时器
QObject::connect(condInfos[i].getTimer(), &QTimer::timeout, [this, i, trigger]() {
condInfos[i].timer->stop();
// 进入下一个
condInfos[i].isProcess = true;
trigger->doTrigger(condInfos[i].funName);
});
condInfos[i].getTimer()->start(condInfos[i].value * 1000);
/*
QTimer::singleShot(info.value * 1000, [&, trigger]() {
// 进入下一个
info.isProcess = true;
trigger->doTrigger(info.funName);
});
*/
}
}
}
void XTaskCondition::reset() {
condInfos.clear();
tmpItems.clear();
}
void XTaskCondition::onTaskEventCheck(const QString& name, const QString& value, const char* value2/* = nullptr*/) {
// 找事件
QVector<XConditionInfo*> conds;
for (auto& info : condInfos) {
if (TRIGGER_CONDITION_TYPE_OPER == info.type) {
for (auto& item : info.items) {
if (0 == item.name.compare(name)) {
conds.push_back(&info);
}
}
}
}
// 返回的是第一个完成事件的条件
XConditionInfo* pInfo = checkMutiConditionInfos(conds, name, value, value2);
if (nullptr == pInfo)
return;
// 结束定时器类型的条件
if(pInfo->getTimer()->isActive())
pInfo->getTimer()->stop();
// 跳转到下一个步骤
pInfo->isProcess = true;
condTrigger->doTrigger(pInfo->funName);
}
void XTaskCondition::setCount(unsigned int count) {
tmpItems.resize(count);
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, bool value) {
setMixedItemValue(objIndex, varIndex, QVariant(value));
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, short value) {
setValue(objIndex, varIndex, (long long)value);
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, int value) {
setValue(objIndex, varIndex, (long long)value);
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, long long value) {
if (ATTR_INDEX_GROUP == varIndex) {
MixedItem& item = getMixedItem(objIndex);
item.groupIndex = (int)value;
}
else if (ATTR_INDEX_INDEX == varIndex) {
MixedItem& item = getMixedItem(objIndex);
item.index = (int)value;
}
else
{
setMixedItemValue(objIndex, varIndex, QVariant(value));
}
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, float value) {
setMixedItemValue(objIndex, varIndex, QVariant(value));
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, double value) {
setMixedItemValue(objIndex, varIndex, QVariant(value));
}
void XTaskCondition::setValue(unsigned int objIndex, unsigned int varIndex, const char* value) {
if (nullptr == value)
return;
if (ATTR_INDEX_NAME == varIndex) {
MixedItem& item = getMixedItem(objIndex);
item.name = QString(value);
}
else
{
setMixedItemValue(objIndex, varIndex, QVariant(value));
}
}
void XTaskCondition::setMixedItemValue(unsigned int objIndex, unsigned int varIndex,const QVariant& value) {
MixedItem& item = getMixedItem(objIndex);
if (ATTR_INDEX_VALUE1 == varIndex)
item.value1 = value;
else
item.value2 = value;
}
XTaskCondition::MixedItem& XTaskCondition::getMixedItem(unsigned int objIndex) {
if (objIndex >= tmpItems.size()) {
tmpItems.resize(objIndex + 1);
}
return tmpItems[objIndex];
}
XTaskCondition::XConditionInfo* XTaskCondition::getConditionInfo(int groupIndex) {
for (auto& info : condInfos) {
if (info.groupIndex == groupIndex)
return&info;
}
return nullptr;
}
bool XTaskCondition::checkPrevMixedItemIsOk(const MixedItem& item) const {
if (0 == item.index)
return true;
return item.isOk;
}
void XTaskCondition::checkMixedItemIsOk( MixedItem& item, const QString& value, const char* value2/* = nullptr*/) {
int vType = item.value1.userType();
bool isOk = false;
if ((int)QVariant::Bool == vType) {
bool rValue = QVariant(value).toBool();
isOk = item.value1.toBool() == rValue;
// 此处忽略第二个值
}
else if((int)QVariant::Int == vType)
{
int rValue = QVariant(value).toInt();
if (0 == item.value2.userType()) {
// 说明没有值
isOk = item.value1.toInt() == rValue;
}
else
{
// 第二个值要进行判断
if (nullptr != value2) {
isOk = areBothInRangeInclusive(rValue, QVariant(value2).toInt(), item.value1.toInt(), item.value2.toInt());
}
}
}
else if ((int)QVariant::LongLong == vType)
{
int rValue = QVariant(value).toLongLong();
if (0 == item.value2.userType()) {
isOk = item.value1.toLongLong() == rValue;
}
else
{
// 第二个值要进行判断
if (nullptr != value2) {
isOk = areBothInRangeInclusive(rValue, QVariant(value2).toLongLong(), item.value1.toLongLong(), item.value2.toLongLong());
}
}
}
else if ((int)QVariant::Double == vType)
{
int rValue = QVariant(value).toDouble();
if (0 == item.value2.userType()) {
isOk = item.value1.toDouble() == rValue;
}
else
{
// 第二个值要进行判断
if (nullptr != value2) {
isOk = areBothInRangeInclusive(rValue, QVariant(value2).toDouble(), item.value1.toDouble(), item.value2.toDouble());
}
}
}
else
{
if (0 == item.value2.userType()) {
isOk = item.value1.toString().contains(value, Qt::CaseInsensitive); // 不区分大小写
}
else
{
// 第二个值要进行判断
if (nullptr != value2) {
isOk = item.value1.toString().contains(QString(value2), Qt::CaseInsensitive); // 不区分大小写
}
}
}
item.isOk = isOk;
}
XTaskCondition::XConditionInfo* XTaskCondition::checkMutiConditionInfos(QVector<XConditionInfo*>& conds,
const QString& name, const QString& value, const char* value2 /*= nullptr*/) {
XConditionInfo* pResult = nullptr;
for (auto pInfo : conds) {
if (checkConditionInfo(pInfo, name, value, value2)) {
if(nullptr == pResult)
pResult = pInfo;
}
}
return pResult;
}
bool XTaskCondition::checkConditionInfo(XConditionInfo* pInfo, const QString& name, const QString& value, const char* value2 /*= nullptr*/) {
QVector<MixedItem>& items = pInfo->items;
for (int i = 0; i < items.size(); ++i) {
MixedItem& item = items[i];
if (0 == item.name.compare(name)) {
// 找到,如果index不为0要判断前面一个
if (1 == items.size() || 0 == item.index || 1 == item.index) {
// 判断值
checkMixedItemIsOk(item, value, value2);
}
else {
MixedItem& prevItem = items[i - 1];
if (checkPrevMixedItemIsOk(prevItem)) {
// 判断值
checkMixedItemIsOk(item, value, value2);
}
}
break;
}
}
// 判断是否完成此步骤
for (auto& item : items) {
if (!item.isOk)
return false;
}
return true;
}