#include "XTaskCondition.h" #include "IVariantProcessor.h" #include "XCTool.h" #include 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 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& 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& 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; }