added autobot run script testcase
This commit is contained in:
parent
e274a2f35e
commit
98b4bb41c7
11 changed files with 213 additions and 19 deletions
|
@ -92,6 +92,8 @@ set(MODULE_SRC
|
|||
${CMAKE_CURRENT_LIST_DIR}/internal/api/autobotapi.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/api/dispatcherapi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/api/dispatcherapi.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/api/navigationapi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/api/navigationapi.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/abfilesmodel.cpp
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "internal/api/logapi.h"
|
||||
#include "internal/api/autobotapi.h"
|
||||
#include "internal/api/dispatcherapi.h"
|
||||
#include "internal/api/navigationapi.h"
|
||||
|
||||
using namespace mu::autobot;
|
||||
using namespace mu::api;
|
||||
|
@ -79,10 +80,11 @@ void AutobotModule::resolveImports()
|
|||
}
|
||||
|
||||
auto api = modularity::ioc()->resolve<IApiRegister>(moduleName());
|
||||
if (ar) {
|
||||
if (api) {
|
||||
api->regApiCreator("global", "api.log", new ApiCreator<LogApi>());
|
||||
api->regApiCreator("autobot", "api.autobot", new ApiCreator<AutobotApi>());
|
||||
api->regApiCreator("autobot", "api.dispatcher", new ApiCreator<DispatcherApi>());
|
||||
api->regApiCreator("autobot", "api.navigation", new ApiCreator<NavigationApi>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "autobotapi.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QEventLoop>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
|
@ -55,13 +54,47 @@ void AutobotApi::setInterval(int msec)
|
|||
m_intervalMsec = msec;
|
||||
}
|
||||
|
||||
void AutobotApi::setTestCase(const QString& name)
|
||||
void AutobotApi::runTestCase(QJSValue testCase)
|
||||
{
|
||||
LOGD() << "test case: " << name;
|
||||
m_testCase.testCase = testCase;
|
||||
m_testCase.steps = testCase.property("steps");
|
||||
m_testCase.stepsCount = m_testCase.steps.property("length").toInt();
|
||||
m_testCase.currentStepIdx = -1;
|
||||
|
||||
nextStep();
|
||||
|
||||
if (m_testCase.currentStepIdx < m_testCase.stepsCount) {
|
||||
m_testCase.loop.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void AutobotApi::step(const QString& name)
|
||||
void AutobotApi::nextStep()
|
||||
{
|
||||
LOGD() << "step: " << name;
|
||||
sleep(m_intervalMsec);
|
||||
m_testCase.currentStepIdx += 1;
|
||||
|
||||
if (m_testCase.currentStepIdx >= m_testCase.stepsCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTimer::singleShot(m_intervalMsec, [this]() {
|
||||
QJSValue step = m_testCase.steps.property(m_testCase.currentStepIdx);
|
||||
QJSValue func = step.property("func");
|
||||
QJSValue wait = step.property("wait");
|
||||
bool isWait = wait.isUndefined() ? true : wait.toBool();
|
||||
|
||||
if (!isWait) {
|
||||
nextStep();
|
||||
}
|
||||
|
||||
func.call();
|
||||
|
||||
if (isWait) {
|
||||
nextStep();
|
||||
}
|
||||
|
||||
m_testCase.finishedCount += 1;
|
||||
if (m_testCase.finishedCount == m_testCase.stepsCount) {
|
||||
m_testCase.loop.quit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#ifndef MU_API_AUTOBOTAPI_H
|
||||
#define MU_API_AUTOBOTAPI_H
|
||||
|
||||
#include <QJSValue>
|
||||
#include <QEventLoop>
|
||||
|
||||
#include "apiobject.h"
|
||||
|
||||
#include "modularity/ioc.h"
|
||||
|
@ -39,15 +42,29 @@ class AutobotApi : public ApiObject
|
|||
public:
|
||||
explicit AutobotApi(IApiEngine* e);
|
||||
|
||||
Q_INVOKABLE void setInterval(int msec);
|
||||
Q_INVOKABLE void runTestCase(QJSValue testCase);
|
||||
|
||||
Q_INVOKABLE bool openProject(const QString& name);
|
||||
|
||||
Q_INVOKABLE void sleep(int msec);
|
||||
|
||||
Q_INVOKABLE void setInterval(int msec);
|
||||
Q_INVOKABLE void setTestCase(const QString& name);
|
||||
Q_INVOKABLE void step(const QString& name);
|
||||
|
||||
private:
|
||||
|
||||
struct TestCase
|
||||
{
|
||||
QJSValue testCase;
|
||||
QJSValue steps;
|
||||
int stepsCount = 0;
|
||||
int currentStepIdx = -1;
|
||||
int finishedCount = 0;
|
||||
QEventLoop loop;
|
||||
};
|
||||
|
||||
void nextStep();
|
||||
|
||||
int m_intervalMsec = 1000;
|
||||
TestCase m_testCase;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
81
src/autobot/internal/api/navigationapi.cpp
Normal file
81
src/autobot/internal/api/navigationapi.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
* MuseScore-CLA-applies
|
||||
*
|
||||
* MuseScore
|
||||
* Music Composition & Notation
|
||||
*
|
||||
* Copyright (C) 2021 MuseScore BVBA and others
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "navigationapi.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
using namespace mu::api;
|
||||
|
||||
NavigationApi::NavigationApi(IApiEngine* e)
|
||||
: ApiObject(e)
|
||||
{
|
||||
}
|
||||
|
||||
void NavigationApi::nextPanel()
|
||||
{
|
||||
dispatcher()->dispatch("nav-next-panel");
|
||||
}
|
||||
|
||||
void NavigationApi::prevPanel()
|
||||
{
|
||||
dispatcher()->dispatch("nav-prev-panel");
|
||||
}
|
||||
|
||||
void NavigationApi::right()
|
||||
{
|
||||
dispatcher()->dispatch("nav-right");
|
||||
}
|
||||
|
||||
void NavigationApi::left()
|
||||
{
|
||||
dispatcher()->dispatch("nav-left");
|
||||
}
|
||||
|
||||
void NavigationApi::up()
|
||||
{
|
||||
dispatcher()->dispatch("nav-up");
|
||||
}
|
||||
|
||||
void NavigationApi::down()
|
||||
{
|
||||
dispatcher()->dispatch("nav-down");
|
||||
}
|
||||
|
||||
bool NavigationApi::goToControlByName(const QString& section, const QString& panel, const QString& contol)
|
||||
{
|
||||
bool ok = navigation()->requestActivateByName(section.toStdString(), panel.toStdString(), contol.toStdString());
|
||||
return ok;
|
||||
}
|
||||
|
||||
void NavigationApi::triggerCurrentControl()
|
||||
{
|
||||
dispatcher()->dispatch("nav-trigger-control");
|
||||
}
|
||||
|
||||
bool NavigationApi::triggerControlByName(const QString& section, const QString& panel, const QString& contol)
|
||||
{
|
||||
bool ok = goToControlByName(section, panel, contol);
|
||||
if (ok) {
|
||||
triggerCurrentControl();
|
||||
}
|
||||
return ok;
|
||||
}
|
55
src/autobot/internal/api/navigationapi.h
Normal file
55
src/autobot/internal/api/navigationapi.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
* MuseScore-CLA-applies
|
||||
*
|
||||
* MuseScore
|
||||
* Music Composition & Notation
|
||||
*
|
||||
* Copyright (C) 2021 MuseScore BVBA and others
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MU_API_NAVIGATIONAPI_H
|
||||
#define MU_API_NAVIGATIONAPI_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "apiobject.h"
|
||||
#include "modularity/ioc.h"
|
||||
#include "actions/iactionsdispatcher.h"
|
||||
#include "ui/inavigationcontroller.h"
|
||||
|
||||
namespace mu::api {
|
||||
class NavigationApi : public ApiObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
INJECT(api, actions::IActionsDispatcher, dispatcher)
|
||||
INJECT(api, ui::INavigationController, navigation)
|
||||
|
||||
public:
|
||||
explicit NavigationApi(IApiEngine* e);
|
||||
|
||||
Q_INVOKABLE void nextPanel();
|
||||
Q_INVOKABLE void prevPanel();
|
||||
Q_INVOKABLE void right();
|
||||
Q_INVOKABLE void left();
|
||||
Q_INVOKABLE void up();
|
||||
Q_INVOKABLE void down();
|
||||
Q_INVOKABLE bool goToControlByName(const QString& section, const QString& panel, const QString& contol);
|
||||
Q_INVOKABLE void triggerCurrentControl();
|
||||
Q_INVOKABLE bool triggerControlByName(const QString& section, const QString& panel, const QString& contol);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MU_API_NAVIGATIONAPI_H
|
|
@ -36,6 +36,7 @@ class ScriptApi : public QObject
|
|||
Q_PROPERTY(QJSValue log READ log CONSTANT)
|
||||
Q_PROPERTY(QJSValue autobot READ autobot CONSTANT)
|
||||
Q_PROPERTY(QJSValue dispatcher READ dispatcher CONSTANT)
|
||||
Q_PROPERTY(QJSValue navigation READ navigation CONSTANT)
|
||||
|
||||
INJECT(api, IApiRegister, apiRegister)
|
||||
|
||||
|
@ -45,6 +46,7 @@ public:
|
|||
QJSValue log() const { return api("api.log"); }
|
||||
QJSValue autobot() const { return api("api.autobot"); }
|
||||
QJSValue dispatcher() const { return api("api.dispatcher"); }
|
||||
QJSValue navigation() const { return api("api.navigation"); }
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -1038,7 +1038,7 @@ void NavigationController::doTriggerControl()
|
|||
bool NavigationController::requestActivateByName(const std::string& sectName, const std::string& panelName, const std::string& controlName)
|
||||
{
|
||||
INavigationSection* section = findByName(m_sections, QString::fromStdString(sectName));
|
||||
if (section) {
|
||||
if (!section) {
|
||||
LOGE() << "not found section with name: " << sectName;
|
||||
return false;
|
||||
}
|
||||
|
@ -1050,16 +1050,16 @@ bool NavigationController::requestActivateByName(const std::string& sectName, co
|
|||
}
|
||||
|
||||
INavigationControl* control = findByName(panel->controls(), QString::fromStdString(controlName));
|
||||
if (!panel) {
|
||||
if (!control) {
|
||||
LOGE() << "not found control with name: " << controlName << ", panel: " << panelName << ", section: " << sectName;
|
||||
return false;
|
||||
}
|
||||
|
||||
onActiveRequested(section, panel, control);
|
||||
onActiveRequested(section, panel, control, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NavigationController::onActiveRequested(INavigationSection* sect, INavigationPanel* panel, INavigationControl* ctrl)
|
||||
void NavigationController::onActiveRequested(INavigationSection* sect, INavigationPanel* panel, INavigationControl* ctrl, bool force)
|
||||
{
|
||||
TRACEFUNC;
|
||||
|
||||
|
@ -1071,13 +1071,13 @@ void NavigationController::onActiveRequested(INavigationSection* sect, INavigati
|
|||
|
||||
//! NOTE If there is no active section,
|
||||
//! we may not be using keyboard navigation, so ignore the request.
|
||||
if (!activeSec) {
|
||||
if (!force && !activeSec) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isChanged = false;
|
||||
|
||||
if (activeSec != sect) {
|
||||
if (activeSec && activeSec != sect) {
|
||||
doDeactivateSection(activeSec);
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ private:
|
|||
void onEscape();
|
||||
|
||||
void doTriggerControl();
|
||||
void onActiveRequested(INavigationSection* sect, INavigationPanel* panel, INavigationControl* ctrl);
|
||||
void onActiveRequested(INavigationSection* sect, INavigationPanel* panel, INavigationControl* ctrl, bool force = false);
|
||||
|
||||
void doActivateSection(INavigationSection* sect, bool isActivateLastPanel = false);
|
||||
void doDeactivateSection(INavigationSection* sect);
|
||||
|
|
|
@ -122,7 +122,7 @@ Item {
|
|||
|
||||
onNavigationActived: {
|
||||
prv.currentItemNavigationIndex = [navigation.row, navigation.column]
|
||||
item.clicked()
|
||||
item.clicked(null)
|
||||
}
|
||||
|
||||
StyledTextLabel {
|
||||
|
|
|
@ -37,6 +37,8 @@ StyledDialogView {
|
|||
contentWidth: 1024
|
||||
resizable: true
|
||||
|
||||
objectName: "NewScoreDialog"
|
||||
|
||||
NewScoreModel {
|
||||
id: newScoreModel
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue