当前位置: 首页>>代码示例>>C++>>正文


C++ actiontools::ActionInstance类代码示例

本文整理汇总了C++中actiontools::ActionInstance的典型用法代码示例。如果您正苦于以下问题:C++ ActionInstance类的具体用法?C++ ActionInstance怎么用?C++ ActionInstance使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了ActionInstance类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: executeCurrentAction

	void Executer::executeCurrentAction()
	{
		//Skip disabled actions
		if(mCurrentActionIndex >= 0)
		{
			while(mCurrentActionIndex < mScript->actionCount() && canExecuteAction(mCurrentActionIndex) != CanExecute)
				++mCurrentActionIndex;
		}

		if(mCurrentActionIndex < 0 || mCurrentActionIndex >= mScript->actionCount())
		{
			stopExecution();
			return;
		}

        int nextLine = mCurrentActionIndex + 2;
		if(nextLine > mScript->actionCount())
			nextLine = -1;

		QScriptValue script = mScriptEngine->globalObject().property("Script");
		script.setProperty("nextLine", mScriptEngine->newVariant(QVariant(nextLine)));
        script.setProperty("line", mCurrentActionIndex + 1, QScriptValue::ReadOnly);

		ActionTools::ActionInstance *actionInstance = currentActionInstance();

        const ActionTools::ExceptionActionInstancesHash &exceptionActionInstancesHash = actionInstance->exceptionActionInstances();
        const ActionTools::ActionException::ExceptionActionInstance &exceptionAction = exceptionActionInstancesHash.value(ActionTools::ActionException::CodeErrorException);
        mShowDebuggerOnCodeError = (exceptionAction.action() == ActionTools::ActionException::StopExecutionExceptionAction);

		mExecutionWindow->setCurrentActionName(actionInstance->definition()->name());
		mExecutionWindow->setCurrentActionColor(actionInstance->color());

		connect(actionInstance, SIGNAL(executionEnded()), this, SLOT(actionExecutionEnded()));
		connect(actionInstance, SIGNAL(executionException(int,QString)), this, SLOT(executionException(int,QString)));
		connect(actionInstance, SIGNAL(disableAction(bool)), this, SLOT(disableAction(bool)));
		connect(actionInstance, SIGNAL(showProgressDialog(QString,int)), this, SLOT(showProgressDialog(QString,int)));
		connect(actionInstance, SIGNAL(updateProgressDialog(int)), this, SLOT(updateProgressDialog(int)));
		connect(actionInstance, SIGNAL(updateProgressDialog(QString)), this, SLOT(updateProgressDialog(QString)));
		connect(actionInstance, SIGNAL(hideProgressDialog()), this, SLOT(hideProgressDialog()));
		connect(actionInstance, SIGNAL(consolePrint(QString)), this, SLOT(consolePrint(QString)));
		connect(actionInstance, SIGNAL(consolePrintWarning(QString)), this, SLOT(consolePrintWarning(QString)));
		connect(actionInstance, SIGNAL(consolePrintError(QString)), this, SLOT(consolePrintError(QString)));
		
		mExecutionStatus = PrePause;

		mExecutionTimer.start();
		mExecutionTime.start();
		if(currentActionInstance()->pauseBefore() + mPauseBefore > 0)
		{
			mExecutionWindow->setProgressEnabled(true);
			mExecutionWindow->setProgressMinimum(0);
			mExecutionWindow->setProgressMaximum(currentActionInstance()->pauseBefore() + mPauseBefore);
			mExecutionWindow->setProgressValue(0);
		}
		else
			mExecutionWindow->setProgressEnabled(false);

		mExecutionEnded = true;
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:59,代码来源:executer.cpp

示例2: undo

void ChangeCommentCommand::undo()
{
	ActionTools::ActionInstance *actionInstance = mModel->mScript->actionAt(mRow);
	if(!actionInstance)
		return;

	actionInstance->setComment(mOld);
    mModel->emitDataChanged(mProxyModel->mapFromSource(mModel->index(mRow, 2)));
}
开发者ID:,项目名称:,代码行数:9,代码来源:

示例3: redo

void ChangeEnabledCommand::redo()
{
	for(int row: mRows)
	{
		ActionTools::ActionInstance *actionInstance = mModel->mScript->actionAt(row);
		if(!actionInstance)
			continue;

		actionInstance->setEnabled(mNew);

		for(int column = 0; column < mModel->columnCount(); ++column)
            mModel->emitDataChanged(mProxyModel->mapFromSource(mModel->index(row, column)));
	}
}
开发者ID:,项目名称:,代码行数:14,代码来源:

示例4: QUndoCommand

//ChangeLabelCommand
ChangeLabelCommand::ChangeLabelCommand(const QString &value, int row, ScriptModel *model, ScriptProxyModel *proxyModel)
	: QUndoCommand(),
	mModel(model),
    mProxyModel(proxyModel),
	mNew(value),
	mRow(row)
{
	ActionTools::ActionInstance *actionInstance = mModel->mScript->actionAt(mRow);
	if(!actionInstance)
		return;

	mOld = actionInstance->label();

	setText(QObject::tr("Change the label from %1 to %2").arg(mOld).arg(mNew));
}
开发者ID:,项目名称:,代码行数:16,代码来源:

示例5: consolePrint

	void Executer::consolePrint(const QString &text, ActionTools::ConsoleWidget::Type type)
	{
		ActionTools::ActionInstance *currentAction = mScript->actionAt(currentActionIndex());
		qint64 currentActionRuntimeId = -1;
		if(currentAction)
			currentActionRuntimeId = currentAction->runtimeId();

		consoleWidget()->addUserLine(text,
									   currentActionRuntimeId,
                                       mScriptEngine->globalObject().property("currentParameter").toString(),
                                       mScriptEngine->globalObject().property("currentSubParameter").toString(),
									   mScriptAgent->currentLine(),
									   mScriptAgent->currentColumn(),
									   mScriptEngine->currentContext()->backtrace(),
									   type);
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:16,代码来源:executer.cpp

示例6: callProcedureFunction

    QScriptValue callProcedureFunction(QScriptContext *context, QScriptEngine *engine)
    {
        if(!Executer::isExecuterRunning())
            return QScriptValue();

        if(context->argumentCount() < 1)
            return engine->undefinedValue();

        QScriptValue calleeData = context->callee().data();
        Executer *executer = qobject_cast<Executer *>(calleeData.toQObject());
        ActionTools::ActionInstance *currentActionInstance = executer->currentActionInstance();

        if(currentActionInstance)
            currentActionInstance->callProcedure(context->argument(0).toString());

        return engine->undefinedValue();
    }
开发者ID:WeDo30,项目名称:actiona,代码行数:17,代码来源:executer.cpp

示例7: canExecuteAction

	Executer::ExecuteActionResult Executer::canExecuteAction(int index) const
	{
		if(index < 0 || index >= mScript->actionCount())
			return IncorrectLine;

		ActionTools::ActionInstance *actionInstance = mScript->actionAt(index);
		if(!actionInstance)
			return InvalidAction;

		if(!mActionEnabled[index] || !actionInstance->isEnabled())
			return DisabledAction;

		if(mExecuteOnlySelection && !actionInstance->isSelected())
			return UnselectedAction;

		return CanExecute;
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:17,代码来源:executer.cpp

示例8: printCall

	void printCall(QScriptContext *context, ActionTools::ConsoleWidget::Type type)
	{
		QApplication::processEvents();//Call this to prevent UI freeze when calling print often

		QScriptValue calleeData = context->callee().data();
		Executer *executer = qobject_cast<Executer *>(calleeData.toQObject());
		QString message;
		ScriptAgent *agent = executer->scriptAgent();

		if(!agent)
			return;
		
		for(int argumentIndex = 0; argumentIndex < context->argumentCount(); ++argumentIndex)
			message += context->argument(argumentIndex).toString();

		switch(executer->scriptAgent()->context())
		{
		case ScriptAgent::Parameters:
			executer->consoleWidget()->addScriptParameterLine(message,
															  agent->currentParameter(),
															  agent->currentLine(),
															  agent->currentColumn(),
															  type);
			break;
		case ScriptAgent::Actions:
			{
				ActionTools::ActionInstance *currentAction = executer->script()->actionAt(executer->currentActionIndex());
				qint64 currentActionRuntimeId = -1;
				if(currentAction)
					currentActionRuntimeId = currentAction->runtimeId();

				executer->consoleWidget()->addUserLine(message,
													   currentActionRuntimeId,
                                                       context->engine()->globalObject().property("currentParameter").toString(),
                                                       context->engine()->globalObject().property("currentSubParameter").toString(),
													   agent->currentLine(),
													   agent->currentColumn(),
													   context->backtrace(),
													   type);
			}
			break;
		default:
			return;
		}
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:45,代码来源:executer.cpp

示例9: pauseOrDebug

	void Executer::pauseOrDebug(bool debug)
	{
		if(mExecutionStatus == Stopped)
			return;

		mExecutionPaused = !mExecutionPaused;

		mPauseInterrupt = !debug;

		if(mScriptEngine->isEvaluating())
		{
			if(mExecutionPaused)
			{
				mScriptEngineDebugger.action(QScriptEngineDebugger::InterruptAction)->trigger();

				if(debug)
					mDebuggerWindow->show();
			}
			else
			{
				mScriptEngineDebugger.action(QScriptEngineDebugger::ContinueAction)->trigger();

				if(debug)
					mDebuggerWindow->hide();
			}

			mScriptAgent->pause(mExecutionPaused);
		}
		else
		{
			ActionTools::ActionInstance *currentAction = currentActionInstance();
			if(currentAction)
			{
				if(mExecutionPaused)
					currentAction->pauseExecution();
				else
					currentAction->resumeExecution();
			}
		}

		mExecutionWindow->setPauseStatus(mExecutionPaused);
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:42,代码来源:executer.cpp

示例10: mimeData

QMimeData* ScriptModel::mimeData(const QModelIndexList &indexes) const
{
	if(indexes.isEmpty())
		return 0;

	QMimeData *mimeDataPtr = new QMimeData();
	QByteArray encodedData;
	QDataStream stream(&encodedData, QIODevice::WriteOnly);

	QList<int> rowIdList;

	for(const QModelIndex &index: indexes)
	{
		if(!index.isValid() || index.column() != ColumnLabel)
			continue;

		if(!rowIdList.contains(index.row()))
			rowIdList << index.row();
	}

    std::sort(rowIdList.begin(), rowIdList.end(), qGreater<int>());

	for(int row: rowIdList)
	{
		ActionTools::ActionInstance *actionInstance = mScript->actionAt(row);

		if(!actionInstance)
			continue;

		stream << row;
		stream << ActionTools::ActionInstanceBuffer(actionInstance->definition()->id(), *actionInstance);
	}

    mimeDataPtr->setData("application/actiona.action", encodedData);
	return mimeDataPtr;
}
开发者ID:sakazuki,项目名称:actiona,代码行数:36,代码来源:scriptmodel.cpp

示例11: updateTimerProgress

	void Executer::updateTimerProgress()
	{
		if(mExecutionPaused)
			return;
		
		ActionTools::ActionInstance *actionInstance = currentActionInstance();
		switch(mExecutionStatus)
		{
		case PrePause:
			if(mExecutionTime.elapsed() >= actionInstance->pauseBefore() + mPauseBefore)
			{
				mExecutionTimer.stop();
				startActionExecution();
			}
			mExecutionWindow->setProgressValue(mExecutionTime.elapsed());
			break;
		case Executing://Timeout
			if(mExecutionTime.elapsed() >= actionInstance->timeout())
			{
				mExecutionTimer.stop();
				actionInstance->disconnect();
				actionInstance->stopExecution();
	
				executionException(ActionTools::ActionException::TimeoutException, QString());
			}
			mExecutionWindow->setProgressValue(mExecutionTime.elapsed());
			break;
		case PostPause:
			if(mExecutionTime.elapsed() >= actionInstance->pauseAfter() + mPauseAfter)
			{
				mExecutionTimer.stop();
				startNextAction();
			}
			mExecutionWindow->setProgressValue(mExecutionTime.elapsed());
			break;
		default:
			Q_ASSERT(false && "updateTimerProgress() called, but execution is stopped");
			break;
		}
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:40,代码来源:executer.cpp

示例12: setData

bool ScriptModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	if(!index.isValid())
		return false;

	if(role == ActionIdRole)
	{
		mScript->setAction(index.row(), mActionFactory->newActionInstance(value.toString()));

		emit dataChanged(index, index);
		emit scriptEdited();

		return true;
	}

	ActionTools::ActionInstance *actionInstance = mScript->actionAt(index.row());
	if(!actionInstance)
		return false;

	if(role == ActionDataRole)
	{
		actionInstance->copyActionDataFrom(value.value<ActionTools::ActionInstance>());

		emit dataChanged(index, index);
		emit scriptEdited();

		return true;
	}

	if(index.column() == ColumnLabel)
	{
		switch(role)
		{
		case Qt::CheckStateRole:
			mUndoStack->push(new ChangeEnabledCommand(QList<int>() << index.row(), value.toBool(), this));

			emit scriptEdited();
			return true;
		case Qt::EditRole:
			QString lineNumber(QString("%1").arg(index.row() + 1, 3, 10, QChar('0')));
			QString labelString(value.toString());
			QString finalValue;

			if(!labelString.isEmpty() && lineNumber != labelString)
			{
				int labelLine = mScript->labelLine(labelString);
				if(labelLine == -1 || labelLine == index.row())
					finalValue = labelString;
			}

			if(labelString == actionInstance->label() || labelString == lineNumber)
				return true;

			mUndoStack->push(new ChangeLabelCommand(finalValue, index.row(), this));

			emit scriptEdited();
			return true;
		}
	}
	else if(index.column() == ColumnComment)
	{
		if(value.toString() == actionInstance->comment())
			return true;

		mUndoStack->push(new ChangeCommentCommand(value.toString(), index.row(), this));

		emit scriptEdited();
		return true;
	}

	return false;
}
开发者ID:sakazuki,项目名称:actiona,代码行数:72,代码来源:scriptmodel.cpp

示例13: startExecution

	bool Executer::startExecution(bool onlySelection)
	{
		Q_ASSERT(mScriptAgent);
		Q_ASSERT(mScriptEngine);
		
	#ifdef ACT_PROFILE
		Tools::HighResolutionTimer timer("Executer::startExecution");
	#endif

        Code::CodeTools::addClassToScriptEngine<CodeActiona>("Actiona", mScriptEngine);
        CodeActiona::setActExec(mIsActExec);
        CodeActiona::setActionaVersion(mActionaVersion);
        CodeActiona::setScriptVersion(mScriptVersion);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::version, "version", mScriptEngine);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::scriptVersion, "scriptVersion", mScriptEngine);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::isActExec, "isActExec", mScriptEngine);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::isActiona, "isActiona", mScriptEngine);
		
		mScriptAgent->setContext(ScriptAgent::ActionInit);
		CodeInitializer::initialize(mScriptEngine, mScriptAgent, mActionFactory);
		mScriptAgent->setContext(ScriptAgent::Parameters);
		
        QScriptValue script = mScriptEngine->newObject();
		mScriptEngine->globalObject().setProperty("Script", script, QScriptValue::ReadOnly);
        script.setProperty("nextLine", 1);
        script.setProperty("line", 1, QScriptValue::ReadOnly);
        QScriptValue callProcedureFun = mScriptEngine->newFunction(callProcedureFunction);
        callProcedureFun.setData(mScriptEngine->newQObject(this));
        script.setProperty("callProcedure", callProcedureFun);

		QScriptValue console = mScriptEngine->newObject();
		mScriptEngine->globalObject().setProperty("Console", console, QScriptValue::ReadOnly);

        QScriptValue function = mScriptEngine->newFunction(printFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("print", function);

        function = mScriptEngine->newFunction(printWarningFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("printWarning", function);

        function = mScriptEngine->newFunction(printErrorFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("printError", function);

        function = mScriptEngine->newFunction(clearConsoleFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("clear", function);

		mExecuteOnlySelection = onlySelection;
		mCurrentActionIndex = 0;
		mActiveActionsCount = 0;
		mExecutionPaused = false;

		bool initSucceeded = true;
		int lastBeginProcedure = -1;

		mScript->clearProcedures();
		mScript->clearCallStack();

        const QHash<QString, ActionTools::Resource> &resources = mScript->resources();
        for(const QString &key: resources.keys())
        {
            const ActionTools::Resource &resource = resources.value(key);
            QScriptValue value;

            switch(resource.type())
            {
            case ActionTools::Resource::BinaryType:
            case ActionTools::Resource::TypeCount:
                value = Code::RawData::constructor(resource.data(), mScriptEngine);
                break;
            case ActionTools::Resource::TextType:
                value = QString::fromUtf8(resource.data(), resource.data().size());
                break;
            case ActionTools::Resource::ImageType:
                {
                    QImage image;

                    if(!image.loadFromData(resource.data()))
                    {
                        mConsoleWidget->addResourceLine(tr("Invalid image resource"), key, ActionTools::ConsoleWidget::Error);

                        return false;
                    }

                    value = Code::Image::constructor(image, mScriptEngine);
                }
                break;
            }

            mScriptEngine->globalObject().setProperty(key, value, QScriptValue::ReadOnly | QScriptValue::Undeletable);
        }

		for(int actionIndex = 0; actionIndex < mScript->actionCount(); ++actionIndex)
		{
			ActionTools::ActionInstance *actionInstance = mScript->actionAt(actionIndex);
			actionInstance->reset();
			actionInstance->clearRuntimeParameters();
			actionInstance->setupExecution(mScriptEngine, mScript, actionIndex);
//.........这里部分代码省略.........
开发者ID:WeDo30,项目名称:actiona,代码行数:101,代码来源:executer.cpp

示例14: executionException

	void Executer::executionException(int exception,
									  const QString &message)
	{
		ActionTools::ActionInstance *actionInstance = currentActionInstance();
		bool standardException = (exception >= 0 && exception < ActionTools::ActionException::ExceptionCount);
		bool customException = false;

		for(ActionTools::ActionException *actionException: actionInstance->definition()->exceptions())
		{
			if(actionException->id() == exception)
			{
				customException = true;
				break;
			}
		}

		if(!standardException && !customException)
		{
			mConsoleWidget->addDesignErrorLine(tr("Action design error: Invalid exception emitted (%1, line %2)")
											   .arg(actionInstance->definition()->name())
											   .arg(mCurrentActionIndex+1), ActionTools::ConsoleWidget::Error);
			stopExecution();
			return;
		}

		ActionTools::ActionException::ExceptionActionInstance exceptionActionInstance = actionInstance->exceptionActionInstance(static_cast<ActionTools::ActionException::Exception>(exception));
		ActionTools::ConsoleWidget::Type exceptionType;
		bool shouldStopExecution;
		switch(exceptionActionInstance.action())
		{
		case ActionTools::ActionException::SkipExceptionAction:
			exceptionType = ActionTools::ConsoleWidget::Information;
			actionExecutionEnded();

			shouldStopExecution = false;
			break;
		case ActionTools::ActionException::GotoLineExceptionAction:
			{
				exceptionType = ActionTools::ConsoleWidget::Information;

				if(canExecuteAction(exceptionActionInstance.line()) != CanExecute)
				{
					ActionTools::ActionInstance *currentAction = mScript->actionAt(mCurrentActionIndex);
					qint64 currentActionRuntimeId = -1;
					if(currentAction)
						currentActionRuntimeId = currentAction->runtimeId();

					mConsoleWidget->addExceptionLine(tr("Invalid exception line: %1").arg(exceptionActionInstance.line()),
													 currentActionRuntimeId,
													 exception,
													 ActionTools::ConsoleWidget::Error);
					shouldStopExecution = true;
				}
				else
				{
					QScriptValue script = mScriptEngine->globalObject().property("Script");
					script.setProperty("nextLine", mScriptEngine->newVariant(QVariant(exceptionActionInstance.line())));
					actionExecutionEnded();
					shouldStopExecution = false;
				}
			}
			break;
		default:
			exceptionType = ActionTools::ConsoleWidget::Error;

			shouldStopExecution = true;
		}

		if(shouldStopExecution)
		{
            QString finalMessage = tr("Script line %1: ").arg(mCurrentActionIndex+1);

			ActionTools::ActionInstance *currentAction = mScript->actionAt(mCurrentActionIndex);
			qint64 currentActionRuntimeId = -1;
			if(currentAction)
				currentActionRuntimeId = currentAction->runtimeId();

			mConsoleWidget->addActionLine(finalMessage + message,
										currentActionRuntimeId,
                                        mScriptEngine->globalObject().property("currentParameter").toString(),
                                        mScriptEngine->globalObject().property("currentSubParameter").toString(),
										mScriptAgent->currentLine(),
										mScriptAgent->currentColumn(),
										exceptionType);

			stopExecution();
		}
	}
开发者ID:WeDo30,项目名称:actiona,代码行数:88,代码来源:executer.cpp

示例15: data

QVariant ScriptModel::data(const QModelIndex &index, int role) const
{
	if(!index.isValid())
		return QVariant();

	ActionTools::ActionInstance *actionInstance = mScript->actionAt(index.row());
	if(!actionInstance)
		return QVariant();

	switch(role)
	{
	case ActionDataRole:
		return QVariant::fromValue(*actionInstance);
	case ActionIdRole:
		return actionInstance->definition()->id();
	case Qt::BackgroundRole:
		{
			const QColor &color = actionInstance->color();

			if(color.isValid())
				return QBrush(color);

			return QBrush();
		}
	case Qt::FontRole:
		{
			if(!actionInstance->definition()->worksUnderThisOS())
			{
				QFont font = QApplication::font();

				font.setItalic(true);

				return font;
			}

			return QFont();
		}
	case Qt::ForegroundRole:
		{
			const QColor &color = actionInstance->color();
			if(color.isValid())
			{
				if(color.lightness() < 128)
					return QBrush(Qt::white);
				else
					return QBrush(Qt::black);
			}
			else
			{
				const QPalette &palette = QApplication::palette();

				if(!actionInstance->isEnabled())
					return QBrush(palette.color(QPalette::Disabled, QPalette::WindowText));

				return QBrush();
			}
		}
	}

	switch(index.column())
	{
	case ColumnLabel:
		switch(role)
		{
			case Qt::CheckStateRole:
				return QVariant(actionInstance->isEnabled() ? Qt::Checked : Qt::Unchecked);
			case Qt::DisplayRole:
			{
				QString labelString = actionInstance->label();
				if(!labelString.isNull() && !labelString.isEmpty())
					return labelString;

				return QString("%1").arg(index.row() + 1, 3, 10, QChar('0'));
			}
			case Qt::EditRole:
				return actionInstance->label();
		}
		break;
	case ColumnActionName:
		switch(role)
		{
			case Qt::ToolTipRole:
				return tr("Double-clic to edit the action");
			case Qt::DisplayRole:
				return actionInstance->definition()->name();
			case Qt::DecorationRole:
				return QIcon(actionInstance->definition()->icon());
			case Qt::TextAlignmentRole:
				return Qt::AlignCenter;
		}
		break;
	case ColumnComment:
		switch(role)
		{
			case Qt::DisplayRole:
			case Qt::EditRole:
				return actionInstance->comment();
		}
		break;
	}
//.........这里部分代码省略.........
开发者ID:sakazuki,项目名称:actiona,代码行数:101,代码来源:scriptmodel.cpp


注:本文中的actiontools::ActionInstance类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。