added script api

This commit is contained in:
Igor Korsukov 2021-10-05 16:57:21 +02:00
parent 790926f0ce
commit a37d49986e
15 changed files with 542 additions and 6 deletions

View file

@ -78,6 +78,16 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdiffdrawstep.h ${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdiffdrawstep.h
${CMAKE_CURRENT_LIST_DIR}/internal/scripts/abscriptengine.cpp ${CMAKE_CURRENT_LIST_DIR}/internal/scripts/abscriptengine.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/scripts/abscriptengine.h ${CMAKE_CURRENT_LIST_DIR}/internal/scripts/abscriptengine.h
${CMAKE_CURRENT_LIST_DIR}/internal/api/iapiengine.h
${CMAKE_CURRENT_LIST_DIR}/internal/api/iapiregister.h
${CMAKE_CURRENT_LIST_DIR}/internal/api/apiregister.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/api/apiregister.h
${CMAKE_CURRENT_LIST_DIR}/internal/api/scriptapi.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/api/scriptapi.h
${CMAKE_CURRENT_LIST_DIR}/internal/api/apiobject.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/api/apiobject.h
${CMAKE_CURRENT_LIST_DIR}/internal/api/logapi.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/api/logapi.h
${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.cpp ${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.cpp
${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.h ${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.h
${CMAKE_CURRENT_LIST_DIR}/view/abfilesmodel.cpp ${CMAKE_CURRENT_LIST_DIR}/view/abfilesmodel.cpp

View file

@ -38,7 +38,11 @@
#include "internal/autobotactions.h" #include "internal/autobotactions.h"
#include "internal/autobotscriptsrepository.h" #include "internal/autobotscriptsrepository.h"
#include "internal/api/apiregister.h"
#include "internal/api/logapi.h"
using namespace mu::autobot; using namespace mu::autobot;
using namespace mu::api;
static const std::shared_ptr<Autobot> s_autobot = std::make_shared<Autobot>(); static const std::shared_ptr<Autobot> s_autobot = std::make_shared<Autobot>();
static std::shared_ptr<AutobotActionsController> s_actionsController = std::make_shared<AutobotActionsController>(); static std::shared_ptr<AutobotActionsController> s_actionsController = std::make_shared<AutobotActionsController>();
@ -54,6 +58,8 @@ void AutobotModule::registerExports()
modularity::ioc()->registerExport<IAutobotConfiguration>(moduleName(), new AutobotConfiguration()); modularity::ioc()->registerExport<IAutobotConfiguration>(moduleName(), new AutobotConfiguration());
modularity::ioc()->registerExport<IAutobotScriptsRepository>(moduleName(), new AutobotScriptsRepository()); modularity::ioc()->registerExport<IAutobotScriptsRepository>(moduleName(), new AutobotScriptsRepository());
modularity::ioc()->registerExport<IApiRegister>(moduleName(), new ApiRegister());
draw::Painter::extended = AbPaintProvider::instance(); draw::Painter::extended = AbPaintProvider::instance();
} }
@ -69,6 +75,11 @@ void AutobotModule::resolveImports()
if (ar) { if (ar) {
ar->reg(std::make_shared<AutobotActions>()); ar->reg(std::make_shared<AutobotActions>());
} }
auto api = modularity::ioc()->resolve<IApiRegister>(moduleName());
if (ar) {
api->regApiCreator("global", "api.log", new ApiCreator<LogApi>());
}
} }
void AutobotModule::registerUiTypes() void AutobotModule::registerUiTypes()

View file

@ -0,0 +1,34 @@
/*
* 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 "apiobject.h"
using namespace mu::api;
ApiObject::ApiObject(IApiEngine* e)
: m_engine(e)
{
}
IApiEngine* ApiObject::engine() const
{
return m_engine;
}

View file

@ -0,0 +1,44 @@
/*
* 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_APIOBJECT_H
#define MU_API_APIOBJECT_H
#include <QObject>
#include "iapiengine.h"
namespace mu::api {
class ApiObject : public QObject
{
Q_OBJECT
public:
explicit ApiObject(IApiEngine* e);
IApiEngine* engine() const;
private:
IApiEngine* m_engine = nullptr;
};
}
#endif // MU_API_APIOBJECT_H

View file

@ -0,0 +1,54 @@
/*
* 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 "apiregister.h"
#include "log.h"
using namespace mu::api;
void ApiRegister::regApiCreator(const std::string& module, const std::string& api, ICreator* c)
{
ApiCreator ac;
auto it = m_creators.find(api);
if (it != m_creators.end()) {
ac = it->second;
}
IF_ASSERT_FAILED(!ac.c) {
LOGE() << "already registred creator for api:" << api << ", before creator will deleted";
delete ac.c;
}
ac.module = module;
ac.c = c;
m_creators[api] = ac;
}
QJSValue ApiRegister::createApi(const std::string& api, IApiEngine* e) const
{
auto it = m_creators.find(api);
if (it == m_creators.end()) {
LOGE() << "not registred creator for api:" << api;
return QJSValue();
}
return it->second.c->create(e);
}

View file

@ -0,0 +1,48 @@
/*
* 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_APIREGISTER_H
#define MU_API_APIREGISTER_H
#include <map>
#include "iapiregister.h"
namespace mu::api {
class ApiRegister : public IApiRegister
{
public:
ApiRegister() = default;
void regApiCreator(const std::string& module, const std::string& api, ICreator* c) override;
QJSValue createApi(const std::string& api, IApiEngine* e) const override;
private:
struct ApiCreator {
std::string module;
ICreator* c = nullptr;
};
std::map<std::string, ApiCreator> m_creators;
};
}
#endif // MU_API_APIREGISTER_H

View file

@ -0,0 +1,38 @@
/*
* 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_IAPIENGINE_H
#define MU_API_IAPIENGINE_H
#include <QJSValue>
#include <QObject>
namespace mu::api {
class IApiEngine
{
public:
virtual ~IApiEngine() = default;
virtual QJSValue newQObject(QObject* o) = 0;
};
}
#endif // MU_API_IAPIENGINE_H

View file

@ -0,0 +1,53 @@
/*
* 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_IAPIREGISTER_H
#define MU_API_IAPIREGISTER_H
#include <QJSValue>
#include "modularity/imoduleexport.h"
#include "iapiengine.h"
namespace mu::api {
class IApiRegister : MODULE_EXPORT_INTERFACE
{
INTERFACE_ID(IApiRegister)
public:
virtual ~IApiRegister() = default;
struct ICreator {
virtual ~ICreator() {}
virtual QJSValue create(IApiEngine* e) = 0;
};
virtual void regApiCreator(const std::string& module, const std::string& api, ICreator* c) = 0;
virtual QJSValue createApi(const std::string& api, IApiEngine* e) const = 0;
};
template<class T>
struct ApiCreator : public IApiRegister::ICreator
{
QJSValue create(IApiEngine* e) { return e->newQObject(new T(e)); }
};
}
#endif // MU_API_IAPIREGISTER_H

View file

@ -0,0 +1,72 @@
/*
* 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 "logapi.h"
#define LOG_TAG "Script"
#include "log.h"
using namespace mu::api;
LogApi::LogApi(IApiEngine* e)
: ApiObject(e)
{
}
void LogApi::error(const QString& message)
{
LOGE() << message;
}
void LogApi::warn(const QString& message)
{
LOGW() << message;
}
void LogApi::info(const QString& message)
{
LOGI() << message;
}
void LogApi::debug(const QString& message)
{
LOGD() << message;
}
void LogApi::error(const QString& tag, const QString& message)
{
LOGE_T(tag.toStdString()) << message;
}
void LogApi::warn(const QString& tag, const QString& message)
{
LOGW_T(tag.toStdString()) << message;
}
void LogApi::info(const QString& tag, const QString& message)
{
LOGI_T(tag.toStdString()) << message;
}
void LogApi::debug(const QString& tag, const QString& message)
{
LOGD_T(tag.toStdString()) << message;
}

View file

@ -0,0 +1,46 @@
/*
* 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_LOGAPI_H
#define MU_API_LOGAPI_H
#include "apiobject.h"
namespace mu::api {
class LogApi : public ApiObject
{
Q_OBJECT
public:
explicit LogApi(IApiEngine* e);
Q_INVOKABLE void error(const QString& message);
Q_INVOKABLE void warn(const QString& message);
Q_INVOKABLE void info(const QString& message);
Q_INVOKABLE void debug(const QString& message);
Q_INVOKABLE void error(const QString& tag, const QString& message);
Q_INVOKABLE void warn(const QString& tag, const QString& message);
Q_INVOKABLE void info(const QString& tag, const QString& message);
Q_INVOKABLE void debug(const QString& tag, const QString& message);
};
}
#endif // LOGAPI_H

View file

@ -0,0 +1,45 @@
/*
* 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 "scriptapi.h"
using namespace mu::api;
ScriptApi::ScriptApi(IApiEngine* engine, QObject* parent)
: QObject(parent), m_engine(engine)
{
}
QJSValue ScriptApi::api(const std::string& name) const
{
if (!apiRegister()) {
return QJSValue();
}
QJSValue val = m_apis.value(name);
if (!val.isUndefined()) {
return val;
}
val = apiRegister()->createApi(name, m_engine);
m_apis[name] = val;
return val;
}

View file

@ -0,0 +1,54 @@
/*
* 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_SCRIPTAPI_H
#define MU_API_SCRIPTAPI_H
#include <QObject>
#include <QMap>
#include "modularity/ioc.h"
#include "iapiregister.h"
#include "iapiengine.h"
namespace mu::api {
class ScriptApi : public QObject
{
Q_OBJECT
Q_PROPERTY(QJSValue log READ log CONSTANT)
INJECT(api, IApiRegister, apiRegister)
public:
ScriptApi(IApiEngine* engine, QObject* parent);
QJSValue log() const { return api("api.log"); }
private:
QJSValue api(const std::string& name) const;
IApiEngine* m_engine = nullptr;
mutable QMap<std::string, QJSValue> m_apis;
};
}
#endif // MU_API_SCRIPTAPI_H

View file

@ -23,9 +23,16 @@
#include "log.h" #include "log.h"
using namespace mu;
using namespace mu::autobot;
using namespace mu::api;
AbScriptEngine::AbScriptEngine() AbScriptEngine::AbScriptEngine()
{ {
m_engine = new QJSEngine(); m_engine = new QJSEngine();
m_api = new ScriptApi(this, m_engine);
m_engine->globalObject().setProperty("api", newQObject(m_api));
} }
AbScriptEngine::~AbScriptEngine() AbScriptEngine::~AbScriptEngine()
@ -151,3 +158,11 @@ Ret AbScriptEngine::jsValueToRet(const QJSValue& val) const
return Ret(Ret::Code::Ok); return Ret(Ret::Code::Ok);
} }
QJSValue AbScriptEngine::newQObject(QObject* o)
{
if (!o->parent()) {
o->setParent(m_engine);
}
return m_engine->newQObject(o);
}

View file

@ -31,8 +31,11 @@
#include "system/ifilesystem.h" #include "system/ifilesystem.h"
#include "ret.h" #include "ret.h"
#include "../api/iapiengine.h"
#include "../api/scriptapi.h"
namespace mu::autobot { namespace mu::autobot {
class AbScriptEngine class AbScriptEngine : public api::IApiEngine
{ {
INJECT(autobot, system::IFileSystem, fileSystem) INJECT(autobot, system::IFileSystem, fileSystem)
public: public:
@ -50,6 +53,9 @@ public:
Ret call(const QString& funcName, QJSValue* retVal = nullptr); Ret call(const QString& funcName, QJSValue* retVal = nullptr);
Ret call(const QString& funcName, const CallData& data, QJSValue* retVal = nullptr); Ret call(const QString& funcName, const CallData& data, QJSValue* retVal = nullptr);
// IApiEngine
QJSValue newQObject(QObject* o) override;
private: private:
RetVal<QByteArray> readScriptContent(const io::path& scriptPath) const; RetVal<QByteArray> readScriptContent(const io::path& scriptPath) const;
@ -63,6 +69,7 @@ private:
}; };
QJSEngine* m_engine = nullptr; QJSEngine* m_engine = nullptr;
api::ScriptApi* m_api = nullptr;
io::path m_scriptPath; io::path m_scriptPath;
QByteArray m_lastEvalScript; QByteArray m_lastEvalScript;
FuncData m_lastCallFunc; FuncData m_lastCallFunc;

View file

@ -27,11 +27,16 @@
#define LOG_STREAM(type, tag) haw::logger::LogInput(type, tag).stream() #define LOG_STREAM(type, tag) haw::logger::LogInput(type, tag).stream()
#define LOG(type, tag) LOG_STREAM(type, tag) << FUNCNAME(FUNC_INFO) << ": " #define LOG(type, tag) LOG_STREAM(type, tag) << FUNCNAME(FUNC_INFO) << ": "
#define LOGE() IF_LOGLEVEL(haw::logger::Normal) LOG(haw::logger::Logger::ERRR, LOG_TAG) #define LOGE_T(tag) IF_LOGLEVEL(haw::logger::Normal) LOG(haw::logger::Logger::ERRR, tag)
#define LOGW() IF_LOGLEVEL(haw::logger::Normal) LOG(haw::logger::Logger::WARN, LOG_TAG) #define LOGW_T(tag) IF_LOGLEVEL(haw::logger::Normal) LOG(haw::logger::Logger::WARN, tag)
#define LOGI() IF_LOGLEVEL(haw::logger::Normal) LOG(haw::logger::Logger::INFO, LOG_TAG) #define LOGI_T(tag) IF_LOGLEVEL(haw::logger::Normal) LOG(haw::logger::Logger::INFO, tag)
#define LOGD() IF_LOGLEVEL(haw::logger::Debug) LOG(haw::logger::Logger::DEBG, LOG_TAG) #define LOGD_T(tag) IF_LOGLEVEL(haw::logger::Debug) LOG(haw::logger::Logger::DEBG, tag)
#define LOGN() if (0) LOG(haw::logger::Logger::DEBG, LOG_TAG) // compiling, but no output
#define LOGE() LOGE_T(LOG_TAG)
#define LOGW() LOGW_T(LOG_TAG)
#define LOGI() LOGI_T(LOG_TAG)
#define LOGD() LOGD_T(LOG_TAG)
#define LOGN() if (0) LOGD_T(LOG_TAG) // compiling, but no output
//! Helps //! Helps
#define DEPRECATED LOGD() << "This function deprecated!!" #define DEPRECATED LOGD() << "This function deprecated!!"