feat: 充分的插件系统和脚本系统的绑定;
This commit is contained in:
parent
b42880aa7e
commit
fb4f439e50
|
@ -7,8 +7,8 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run clang-format style check for C/C++/Protobuf programs.
|
||||
uses: jidicula/clang-format-action@v4.14.0
|
||||
uses: jidicula/clang-format-action@v4.15.0
|
||||
with:
|
||||
clang-format-version: '19'
|
||||
clang-format-version: '20'
|
||||
exclude-regex: '(qt-template|mkinstaller|grammar)'
|
||||
fallback-style: 'LLVM' # optional
|
||||
|
|
|
@ -298,7 +298,11 @@ set(CLASS_SRC
|
|||
src/class/asconsolecompletion.h
|
||||
src/class/asconsolecompletion.cpp
|
||||
src/class/scriptsettings.h
|
||||
src/class/scriptsettings.cpp)
|
||||
src/class/scriptsettings.cpp
|
||||
src/class/wingangel.h
|
||||
src/class/wingangel.cpp
|
||||
src/class/winggeneric.h
|
||||
src/class/winggeneric.cpp)
|
||||
|
||||
set(INTERNAL_PLG_SRC
|
||||
src/class/wingangelapi.h src/class/wingangelapi.cpp
|
||||
|
|
|
@ -269,60 +269,60 @@
|
|||
<context>
|
||||
<name>TestPlugin</name>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="204"/>
|
||||
<location filename="../testplugin.cpp" line="69"/>
|
||||
<source>Test</source>
|
||||
<translation>测试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="216"/>
|
||||
<location filename="../testplugin.cpp" line="225"/>
|
||||
<location filename="../testplugin.cpp" line="230"/>
|
||||
<location filename="../testplugin.cpp" line="299"/>
|
||||
<location filename="../testplugin.cpp" line="81"/>
|
||||
<location filename="../testplugin.cpp" line="90"/>
|
||||
<location filename="../testplugin.cpp" line="95"/>
|
||||
<location filename="../testplugin.cpp" line="164"/>
|
||||
<source>TestPlugin</source>
|
||||
<translation>测试插件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="234"/>
|
||||
<location filename="../testplugin.cpp" line="99"/>
|
||||
<source>Button - </source>
|
||||
<translation>按钮 - </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="238"/>
|
||||
<location filename="../testplugin.cpp" line="103"/>
|
||||
<source>Click</source>
|
||||
<translation>点击</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="302"/>
|
||||
<location filename="../testplugin.cpp" line="167"/>
|
||||
<source>A Test Plugin for WingHexExplorer2.</source>
|
||||
<translation>一个用来测试羽云十六进制编辑器2的插件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="336"/>
|
||||
<location filename="../testplugin.cpp" line="344"/>
|
||||
<location filename="../testplugin.cpp" line="353"/>
|
||||
<location filename="../testplugin.cpp" line="374"/>
|
||||
<location filename="../testplugin.cpp" line="390"/>
|
||||
<location filename="../testplugin.cpp" line="397"/>
|
||||
<location filename="../testplugin.cpp" line="404"/>
|
||||
<location filename="../testplugin.cpp" line="411"/>
|
||||
<location filename="../testplugin.cpp" line="419"/>
|
||||
<location filename="../testplugin.cpp" line="448"/>
|
||||
<location filename="../testplugin.cpp" line="456"/>
|
||||
<location filename="../testplugin.cpp" line="464"/>
|
||||
<location filename="../testplugin.cpp" line="472"/>
|
||||
<location filename="../testplugin.cpp" line="481"/>
|
||||
<location filename="../testplugin.cpp" line="488"/>
|
||||
<location filename="../testplugin.cpp" line="196"/>
|
||||
<location filename="../testplugin.cpp" line="204"/>
|
||||
<location filename="../testplugin.cpp" line="213"/>
|
||||
<location filename="../testplugin.cpp" line="234"/>
|
||||
<location filename="../testplugin.cpp" line="250"/>
|
||||
<location filename="../testplugin.cpp" line="257"/>
|
||||
<location filename="../testplugin.cpp" line="264"/>
|
||||
<location filename="../testplugin.cpp" line="271"/>
|
||||
<location filename="../testplugin.cpp" line="278"/>
|
||||
<location filename="../testplugin.cpp" line="307"/>
|
||||
<location filename="../testplugin.cpp" line="315"/>
|
||||
<location filename="../testplugin.cpp" line="323"/>
|
||||
<location filename="../testplugin.cpp" line="331"/>
|
||||
<location filename="../testplugin.cpp" line="340"/>
|
||||
<location filename="../testplugin.cpp" line="347"/>
|
||||
<source>InvalidParamsCount</source>
|
||||
<translation>无效参数个数</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="367"/>
|
||||
<location filename="../testplugin.cpp" line="383"/>
|
||||
<location filename="../testplugin.cpp" line="227"/>
|
||||
<location filename="../testplugin.cpp" line="243"/>
|
||||
<source>InvalidParam</source>
|
||||
<translation>非法参数</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="439"/>
|
||||
<location filename="../testplugin.cpp" line="298"/>
|
||||
<source>AllocArrayFailed</source>
|
||||
<translation>分配数组失败</translation>
|
||||
</message>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "testplugin.h"
|
||||
#include "WingPlugin/iwingangel.h"
|
||||
#include "testform.h"
|
||||
#include "testsettingpage.h"
|
||||
#include "testwingeditorviewwidget.h"
|
||||
|
@ -26,6 +27,8 @@
|
|||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
|
||||
WING_DECLARE_STATIC_API;
|
||||
|
||||
// 注意:所有提供的脚本接口函数都不是线程安全的,只是测试
|
||||
|
||||
TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
|
||||
|
@ -36,145 +39,7 @@ TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
|
|||
// 初始化会传递一个配置类,插件系统会统一管理放到统一的地方,使用 INI 保存
|
||||
// 你可以自行管理,但不建议,统一管理方便使用者备份和转移插件配置
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_a),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
_scriptInfo.insert(QStringLiteral("test_a"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_b),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
info.params.append(qMakePair(MetaType::String, QStringLiteral("info")));
|
||||
_scriptInfo.insert(QStringLiteral("test_b"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_c),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
info.params.append(
|
||||
qMakePair(MetaType::Int | MetaType::Array, QStringLiteral("c")));
|
||||
_scriptInfo.insert(QStringLiteral("test_c"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_d),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
info.params.append(qMakePair(MetaType::Hash, QStringLiteral("d")));
|
||||
_scriptInfo.insert(QStringLiteral("test_d"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_e),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
_scriptInfo.insert(QStringLiteral("test_e"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_f),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Byte | MetaType::Array;
|
||||
_scriptInfo.insert(QStringLiteral("test_f"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_g),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::String;
|
||||
_scriptInfo.insert(QStringLiteral("test_g"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn =
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_h),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Hash;
|
||||
_scriptInfo.insert(QStringLiteral("test_h"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::createTestShareMem),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
info.params.append(
|
||||
qMakePair(MetaType::String, QStringLiteral("nameID")));
|
||||
_scriptInfo.insert(QStringLiteral("createTestShareMem"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::destoryTestShareMem),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
_scriptInfo.insert(QStringLiteral("destoryTestShareMem"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::printLogTestSharedMemData),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
_scriptInfo.insert(QStringLiteral("printLogTestSharedMemData"), info);
|
||||
}
|
||||
|
||||
{
|
||||
_scriptUnsafe.insert(QStringLiteral("array<color>@ colorTable()"),
|
||||
std::bind(QOverload<const QList<void *> &>::of(
|
||||
&TestPlugin::colorTable),
|
||||
this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::setPluginMetaTestEnabled),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
info.params.append(qMakePair(MetaType::Bool, QStringLiteral("b")));
|
||||
_scriptInfo.insert(QStringLiteral("setPluginMetaTestEnabled"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::pluginMetaTestEnabled),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
_scriptInfo.insert(QStringLiteral("pluginMetaTestEnabled"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&TestPlugin::testCrash), this,
|
||||
std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
_scriptInfo.insert(QStringLiteral("testCrash"), info);
|
||||
}
|
||||
WING_INIT_STATIC_API;
|
||||
}
|
||||
|
||||
TestPlugin::~TestPlugin() { destoryTestShareMem(); }
|
||||
|
@ -326,11 +191,6 @@ TestPlugin::registeredEditorViewWidgets() const {
|
|||
return _evws;
|
||||
}
|
||||
|
||||
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR>
|
||||
TestPlugin::registeredScriptUnsafeFns() const {
|
||||
return _scriptUnsafe;
|
||||
}
|
||||
|
||||
QVariant TestPlugin::test_a(const QVariantList ¶ms) {
|
||||
if (!params.isEmpty()) {
|
||||
return getScriptCallError(-1, tr("InvalidParamsCount"));
|
||||
|
@ -413,8 +273,7 @@ QVariant TestPlugin::test_h(const QVariantList ¶ms) {
|
|||
return test_h();
|
||||
}
|
||||
|
||||
WingHex::IWingPlugin::UNSAFE_RET
|
||||
TestPlugin::colorTable(const QList<void *> ¶ms) {
|
||||
WingHex::UNSAFE_RET TestPlugin::colorTable(const QList<void *> ¶ms) {
|
||||
if (!params.isEmpty()) {
|
||||
return generateScriptCallError(-1, tr("InvalidParamsCount"));
|
||||
}
|
||||
|
@ -427,7 +286,7 @@ TestPlugin::colorTable(const QList<void *> ¶ms) {
|
|||
|
||||
auto invoked =
|
||||
invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray",
|
||||
qReturnArg(array), MetaType::Color, colors);
|
||||
qReturnArg(array), WingHex::MetaType::Meta_Color, colors);
|
||||
if (invoked) {
|
||||
if (array) {
|
||||
qDeleteAll(colors);
|
||||
|
@ -491,6 +350,19 @@ QVariant TestPlugin::testCrash(const QVariantList ¶ms) {
|
|||
return {};
|
||||
}
|
||||
|
||||
void TestPlugin::testGenericAdd(WingHex::asIWingGeneric *param) {
|
||||
auto g = QScopedPointer<WingHex::IWingGeneric>(createParamContext(param));
|
||||
|
||||
auto arg0 = g->argDWord(0);
|
||||
auto arg1 = g->argDWord(1);
|
||||
|
||||
g->setReturnDWord(arg0 + arg1);
|
||||
}
|
||||
|
||||
void TestPlugin::testRaiseScriptException(WingHex::asIWingGeneric *) {
|
||||
raiseContextException(__func__, true);
|
||||
}
|
||||
|
||||
void TestPlugin::test_a() { logDebug(__FUNCTION__); }
|
||||
|
||||
void TestPlugin::test_b(const QString &b) {
|
||||
|
@ -608,15 +480,9 @@ void TestPlugin::testCrash() {
|
|||
abort();
|
||||
}
|
||||
|
||||
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo>
|
||||
TestPlugin::registeredScriptFns() const {
|
||||
return _scriptInfo;
|
||||
}
|
||||
|
||||
WingHex::IWingPlugin::RegisteredEvents TestPlugin::registeredEvents() const {
|
||||
RegisteredEvents evs;
|
||||
evs.setFlag(RegisteredEvent::AppReady);
|
||||
evs.setFlag(RegisteredEvent::ScriptUnSafeFnRegistering);
|
||||
return evs;
|
||||
}
|
||||
|
||||
|
@ -626,3 +492,113 @@ void TestPlugin::eventReady() {
|
|||
Qt::AutoConnection, qReturnArg(ret),
|
||||
QStringLiteral(R"(print("Hello, this is TestPlugin!");)"));
|
||||
}
|
||||
|
||||
void TestPlugin::onRegisterScriptObj(WingHex::IWingAngel *o) {
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_a),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_a"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_b),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_b"),
|
||||
{qMakePair(WingHex::MetaType::Meta_String, QStringLiteral("info"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_c),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_c"),
|
||||
{qMakePair(WingHex::MetaType::Meta_Int | WingHex::MetaType::Meta_Array,
|
||||
QStringLiteral("c"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_d),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_d"),
|
||||
{qMakePair(WingHex::MetaType::Meta_Hash, QStringLiteral("d"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Bool,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_e),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_e"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Byte | WingHex::MetaType::Meta_Array,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_f),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_f"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_String,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_g),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_g"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Hash,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_h),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("test_h"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Bool,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::createTestShareMem),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("createTestShareMem"),
|
||||
{qMakePair(WingHex::MetaType::Meta_String, QStringLiteral("nameID"))});
|
||||
|
||||
o->registerGlobalFunction(WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::destoryTestShareMem),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("destoryTestShareMem"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::printLogTestSharedMemData),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("printLogTestSharedMemData"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
QStringLiteral("array<color>@ colorTable()"),
|
||||
std::bind(QOverload<const QList<void *> &>::of(&TestPlugin::colorTable),
|
||||
this, std::placeholders::_1));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::setPluginMetaTestEnabled),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("setPluginMetaTestEnabled"),
|
||||
{qMakePair(WingHex::MetaType::Meta_Bool, QStringLiteral("b"))});
|
||||
|
||||
o->registerGlobalFunction(WingHex::MetaType::Meta_Bool,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&TestPlugin::pluginMetaTestEnabled),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("pluginMetaTestEnabled"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::MetaType::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::testCrash),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("testCrash"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
"int testAdd(int a,int b)", asWINGFUNCTION(TestPlugin::testGenericAdd),
|
||||
WingHex::IWingAngel::asCallConvTypes::asCALL_GENERIC);
|
||||
|
||||
o->registerGlobalFunction(
|
||||
"void raiseScriptException()",
|
||||
asWINGFUNCTION(TestPlugin::testRaiseScriptException),
|
||||
WingHex::IWingAngel::asCallConvTypes::asCALL_GENERIC);
|
||||
}
|
||||
|
|
|
@ -60,14 +60,14 @@ public:
|
|||
registeredSettingPages() const override;
|
||||
virtual QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
|
||||
registeredEditorViewWidgets() const override;
|
||||
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
|
||||
|
||||
virtual QHash<QString, UNSAFE_SCFNPTR>
|
||||
registeredScriptUnsafeFns() const override;
|
||||
|
||||
virtual RegisteredEvents registeredEvents() const override;
|
||||
virtual void eventReady() override;
|
||||
|
||||
// IWingPluginCoreBase interface
|
||||
public:
|
||||
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
|
||||
|
||||
private:
|
||||
QVariant test_a(const QVariantList ¶ms);
|
||||
QVariant test_b(const QVariantList ¶ms);
|
||||
|
@ -79,7 +79,7 @@ private:
|
|||
QVariant test_g(const QVariantList ¶ms);
|
||||
QVariant test_h(const QVariantList ¶ms);
|
||||
|
||||
UNSAFE_RET colorTable(const QList<void *> ¶ms);
|
||||
WingHex::UNSAFE_RET colorTable(const QList<void *> ¶ms);
|
||||
|
||||
QVariant createTestShareMem(const QVariantList ¶ms);
|
||||
QVariant destoryTestShareMem(const QVariantList ¶ms);
|
||||
|
@ -90,6 +90,10 @@ private:
|
|||
|
||||
QVariant testCrash(const QVariantList ¶ms);
|
||||
|
||||
static void testGenericAdd(WingHex::asIWingGeneric *param);
|
||||
|
||||
static void testRaiseScriptException(WingHex::asIWingGeneric *);
|
||||
|
||||
private:
|
||||
void test_a();
|
||||
void test_b(const QString &b);
|
||||
|
@ -119,13 +123,10 @@ private:
|
|||
|
||||
bool ENABLE_META = false;
|
||||
|
||||
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo> _scriptInfo;
|
||||
QList<WingHex::WingDockWidgetInfo> _winfo;
|
||||
QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo;
|
||||
QList<WingHex::SettingPage *> _setpages;
|
||||
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> _evws;
|
||||
|
||||
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
|
||||
};
|
||||
|
||||
#endif // TESTPLUGIN_H
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ec5bcd41309e175aa262f367011c1ad9fe7e9b31
|
||||
Subproject commit cdaf256c8a44e724cc295e5b23cc291ac2414c02
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -16,15 +16,15 @@
|
|||
*/
|
||||
|
||||
#include "pluginsystem.h"
|
||||
#include "AngelScript/sdk/angelscript/source/as_builder.h"
|
||||
#include "Qt-Advanced-Docking-System/src/DockAreaWidget.h"
|
||||
#include "class/languagemanager.h"
|
||||
#include "class/logger.h"
|
||||
#include "class/scriptmachine.h"
|
||||
#include "class/settingmanager.h"
|
||||
#include "class/skinmanager.h"
|
||||
#include "class/wingangel.h"
|
||||
#include "class/wingcstruct.h"
|
||||
#include "class/wingfiledialog.h"
|
||||
#include "class/winggeneric.h"
|
||||
#include "class/winginputdialog.h"
|
||||
#include "class/wingmessagebox.h"
|
||||
#include "control/toast.h"
|
||||
|
@ -74,17 +74,6 @@ PluginSystem::PluginSystem(QObject *parent) : QObject(parent) {
|
|||
|
||||
PluginSystem::~PluginSystem() {}
|
||||
|
||||
void PluginSystem::initCheckingEngine() {
|
||||
_engine = dynamic_cast<asCScriptEngine *>(asCreateScriptEngine());
|
||||
Q_ASSERT(_engine);
|
||||
|
||||
// basic checking environment
|
||||
ScriptMachine::registerEngineAddon(_engine);
|
||||
_angelplg->installBasicTypes(_engine);
|
||||
}
|
||||
|
||||
void PluginSystem::finalizeCheckingEngine() { _engine->ShutDownAndRelease(); }
|
||||
|
||||
// =========================================================================
|
||||
|
||||
void PluginSystem::toast(const QObject *sender, const QPixmap &icon,
|
||||
|
@ -2498,6 +2487,33 @@ bool PluginSystem::closeAllFiles(const QObject *sender) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void PluginSystem::__raiseContextException(const QObject *sender,
|
||||
const QString &exception,
|
||||
bool allowCatch) {
|
||||
if (passByFailedGuard(sender, __func__, {})) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto ctx = asGetActiveContext();
|
||||
if (ctx) {
|
||||
auto info = exception.toUtf8();
|
||||
ctx->SetException(info, allowCatch);
|
||||
}
|
||||
}
|
||||
|
||||
IWingGeneric *PluginSystem::__createParamContext(const QObject *sender,
|
||||
void *ctx) {
|
||||
if (passByFailedGuard(sender, __func__, {})) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto gen = reinterpret_cast<asIScriptGeneric *>(ctx);
|
||||
if (gen) {
|
||||
return new WingGeneric(gen);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PluginSystem::passByFailedGuard(const QObject *sender, const char *func,
|
||||
const QVariantList ¶ms) {
|
||||
if (_manager && sender != _manager) {
|
||||
|
@ -2520,6 +2536,30 @@ bool PluginSystem::checkErrAllAllowAndReport(const QObject *sender,
|
|||
return false;
|
||||
}
|
||||
|
||||
void PluginSystem::doneRegisterScriptObj() {
|
||||
Q_ASSERT(_angelplg);
|
||||
// ok, then, we will register all script objects
|
||||
auto api =
|
||||
QScopedPointer<WingAngel>(new WingAngel(_angelplg, _scriptMarcos));
|
||||
auto ptr = api.data();
|
||||
if (_manager) {
|
||||
ptr->setCurrentPluginSession(_manInfo->id.toUtf8());
|
||||
_manager->onRegisterScriptObj(ptr);
|
||||
}
|
||||
|
||||
for (auto &p : _loadedplgs) {
|
||||
auto puid = getPUID(p);
|
||||
ptr->setCurrentPluginSession(puid.toUtf8());
|
||||
p->onRegisterScriptObj(ptr);
|
||||
}
|
||||
|
||||
for (auto &p : _loadeddevs) {
|
||||
auto puid = getPUID(p);
|
||||
ptr->setCurrentPluginSession(puid.toUtf8());
|
||||
p->onRegisterScriptObj(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
const std::optional<PluginInfo> &PluginSystem::monitorManagerInfo() const {
|
||||
return _manInfo;
|
||||
}
|
||||
|
@ -3218,6 +3258,7 @@ PluginInfo PluginSystem::parsePluginMetadata(const QJsonObject &meta) {
|
|||
PluginInfo info;
|
||||
|
||||
info.id = meta["Id"].toString().trimmed();
|
||||
|
||||
info.SDKVersion = meta["SDK"].toInt();
|
||||
info.version =
|
||||
QVersionNumber::fromString(meta["Version"].toString().trimmed());
|
||||
|
@ -3264,7 +3305,7 @@ PluginSystem::checkPluginMetadata(const PluginInfo &meta, bool isPlg) {
|
|||
return PluginStatus::InvalidID;
|
||||
}
|
||||
|
||||
if (!isValidIdentifier(meta.id)) {
|
||||
if (!Utilities::isValidIdentifier(meta.id)) {
|
||||
return PluginStatus::InvalidID;
|
||||
}
|
||||
|
||||
|
@ -3284,23 +3325,6 @@ PluginSystem::checkPluginMetadata(const PluginInfo &meta, bool isPlg) {
|
|||
return PluginStatus::Valid;
|
||||
}
|
||||
|
||||
bool PluginSystem::isValidIdentifier(const QString &str) {
|
||||
if (str.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
auto pch = str.cbegin();
|
||||
if (pch->isDigit()) {
|
||||
return false;
|
||||
}
|
||||
pch++;
|
||||
for (; pch != str.cend(); pch++) {
|
||||
if (!pch->isLetterOrNumber() && *pch != '_') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PluginSystem::checkPluginCanOpenedFile(IWingPlugin *plg) {
|
||||
if (plg == nullptr) {
|
||||
return false;
|
||||
|
@ -3750,6 +3774,7 @@ void PluginSystem::try2LoadManagerPlugin() {
|
|||
|
||||
applyFunctionTables(p, _plgFns);
|
||||
_manager = p;
|
||||
registerPluginDetectMarco(m.id);
|
||||
|
||||
// translate the meta-data
|
||||
m.author = p->retranslate(m.author);
|
||||
|
@ -3764,223 +3789,9 @@ void PluginSystem::try2LoadManagerPlugin() {
|
|||
}
|
||||
}
|
||||
|
||||
void PluginSystem::registerFns(IWingPlugin *plg) {
|
||||
if (_angelplg == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(plg);
|
||||
auto fns = plg->registeredScriptFns();
|
||||
if (fns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// checking functions
|
||||
asCBuilder c(_engine, nullptr);
|
||||
|
||||
auto id = getPluginID(plg);
|
||||
auto rawID = id.toUtf8();
|
||||
|
||||
QList<asCScriptFunction *> fnlist;
|
||||
|
||||
auto r = _engine->SetDefaultNamespace(rawID);
|
||||
if (Q_UNLIKELY(r < 0)) {
|
||||
_engine->configFailed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// <signatures, std::function>
|
||||
QHash<QString, IWingPlugin::ScriptFnInfo> rfns;
|
||||
for (auto p = fns.constKeyValueBegin(); p != fns.constKeyValueEnd(); ++p) {
|
||||
auto func = new asCScriptFunction(_engine, nullptr, asFUNC_SYSTEM);
|
||||
|
||||
auto &fn = p->second;
|
||||
auto sig = getScriptFnSig(p->first, fn);
|
||||
if (sig.isEmpty()) {
|
||||
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + id +
|
||||
QStringLiteral("::") + p->first);
|
||||
func->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto r = c.ParseFunctionDeclaration(nullptr, sig.toLatin1(), func, true,
|
||||
nullptr, nullptr,
|
||||
_engine->defaultNamespace);
|
||||
if (r < 0) {
|
||||
Logger::critical(tr("RegisterScriptFnInvalidSig:") + sig);
|
||||
func->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
r = c.CheckNameConflict(func->name.AddressOf(), 0, 0,
|
||||
_engine->defaultNamespace, false, false, false);
|
||||
if (r < 0) {
|
||||
Logger::critical(tr("RegisterScriptFnConflitSig:") + sig);
|
||||
func->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
fnlist.append(func);
|
||||
|
||||
// register functions with internal hacking
|
||||
func->id = _engine->GetNextScriptFunctionId();
|
||||
_engine->AddScriptFunction(func);
|
||||
rfns.insert(sig, p->second);
|
||||
}
|
||||
|
||||
// clear the internal hacking functions
|
||||
for (auto &fn : fnlist) {
|
||||
_engine->RemoveScriptFunction(fn);
|
||||
}
|
||||
_engine->SetDefaultNamespace("");
|
||||
|
||||
fnlist.clear();
|
||||
|
||||
Q_ASSERT(_angelplg);
|
||||
_angelplg->registerScriptFns(_pinfos.value(plg).id, rfns);
|
||||
}
|
||||
|
||||
void PluginSystem::registerUnSafeFns(IWingPlugin *plg) {
|
||||
if (_angelplg == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(plg);
|
||||
|
||||
auto fns = plg->registeredScriptUnsafeFns();
|
||||
if (fns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// checking functions
|
||||
asCBuilder c(_engine, nullptr);
|
||||
|
||||
auto id = getPluginID(plg);
|
||||
auto rawID = id.toUtf8();
|
||||
|
||||
QList<asCScriptFunction *> fnlist;
|
||||
|
||||
auto r = _engine->SetDefaultNamespace(rawID);
|
||||
if (Q_UNLIKELY(r < 0)) {
|
||||
_engine->configFailed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// <signatures, std::function>
|
||||
QHash<QString, IWingPlugin::UNSAFE_SCFNPTR> rfns;
|
||||
for (auto p = fns.constKeyValueBegin(); p != fns.constKeyValueEnd(); ++p) {
|
||||
auto func = new asCScriptFunction(_engine, nullptr, asFUNC_SYSTEM);
|
||||
auto sig = p->first;
|
||||
auto r = c.ParseFunctionDeclaration(nullptr, sig.toLatin1(), func, true,
|
||||
nullptr, nullptr,
|
||||
_engine->defaultNamespace);
|
||||
if (r < 0) {
|
||||
Logger::critical(tr("RegisterScriptFnInvalidSig:") + sig);
|
||||
func->funcType = asFUNC_DUMMY;
|
||||
continue;
|
||||
}
|
||||
|
||||
r = c.CheckNameConflict(func->name.AddressOf(), 0, 0,
|
||||
_engine->defaultNamespace, false, false, false);
|
||||
if (r < 0) {
|
||||
Logger::critical(tr("RegisterScriptFnConflitSig:") + sig);
|
||||
func->funcType = asFUNC_DUMMY;
|
||||
continue;
|
||||
}
|
||||
|
||||
fnlist.append(func);
|
||||
|
||||
// register functions with internal hacking
|
||||
func->id = _engine->GetNextScriptFunctionId();
|
||||
_engine->AddScriptFunction(func);
|
||||
rfns.insert(sig, p->second);
|
||||
}
|
||||
|
||||
// clear the internal hacking functions
|
||||
for (auto &fn : fnlist) {
|
||||
_engine->RemoveScriptFunction(fn);
|
||||
}
|
||||
_engine->SetDefaultNamespace("");
|
||||
|
||||
fnlist.clear();
|
||||
|
||||
Q_ASSERT(_angelplg);
|
||||
_angelplg->registerUnSafeScriptFns(_pinfos.value(plg).id, rfns);
|
||||
}
|
||||
|
||||
void PluginSystem::registerEnums(IWingPlugin *plg) {
|
||||
Q_ASSERT(plg);
|
||||
auto objs = plg->registeredScriptEnums();
|
||||
if (objs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
decltype(objs) passedEnums;
|
||||
|
||||
// checking enums
|
||||
// Here we just register the enum in real action.
|
||||
// If failed, we can hack and restore the engine.
|
||||
auto id = getPluginID(plg);
|
||||
auto r = _engine->SetDefaultNamespace(id.toUtf8());
|
||||
if (Q_UNLIKELY(r < 0)) {
|
||||
_engine->configFailed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// not neccssary to really restore when failed, 'cause of unique
|
||||
// namespace
|
||||
for (auto el = objs.constKeyValueBegin(); el != objs.constKeyValueEnd();
|
||||
++el) {
|
||||
auto ename = el->first.toUtf8();
|
||||
auto r = _engine->RegisterEnum(ename);
|
||||
if (r < 0) {
|
||||
Logger::critical(tr("InvalidEnumName:") + el->first);
|
||||
_engine->configFailed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool hasNoError = true;
|
||||
for (auto &ev : el->second) {
|
||||
r = _engine->RegisterEnumValue(ename, ev.first.toUtf8(), ev.second);
|
||||
if (r < 0) {
|
||||
Logger::critical(
|
||||
tr("InvalidEnumValue:") + el->first + QStringLiteral("::") +
|
||||
ev.first + QStringLiteral(" (") +
|
||||
QString::number(ev.second) + QStringLiteral(")"));
|
||||
_engine->configFailed = false;
|
||||
hasNoError = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasNoError) {
|
||||
passedEnums.insert(el->first, el->second);
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(_angelplg);
|
||||
_angelplg->registerScriptEnums(id, passedEnums);
|
||||
}
|
||||
|
||||
void PluginSystem::registerMarcos(IWingPlugin *plg) {
|
||||
Q_ASSERT(plg);
|
||||
|
||||
auto id = getPUID(plg).toUpper();
|
||||
auto sep = QStringLiteral("_");
|
||||
void PluginSystem::registerPluginDetectMarco(const QString &id) {
|
||||
static auto sep = QStringLiteral("_");
|
||||
_scriptMarcos.append(sep + id + sep);
|
||||
|
||||
QStringList invalidMarco;
|
||||
for (auto &m : plg->registerScriptMarcos()) {
|
||||
if (isValidIdentifier(m)) {
|
||||
_scriptMarcos.append(sep + id + sep + m + sep);
|
||||
} else {
|
||||
invalidMarco.append(m);
|
||||
}
|
||||
}
|
||||
|
||||
if (!invalidMarco.isEmpty()) {
|
||||
Logger::warning(tr("InvalidMarcosRegister:") + invalidMarco.join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
void PluginSystem::registerEvents(IWingPlugin *plg) {
|
||||
|
@ -4039,10 +3850,6 @@ void PluginSystem::registerEvents(IWingPlugin *plg) {
|
|||
if (evs.testFlag(IWingPlugin::RegisteredEvent::PluginFileClosed)) {
|
||||
_evplgs[IWingPlugin::RegisteredEvent::PluginFileClosed].append(plg);
|
||||
}
|
||||
|
||||
if (evs.testFlag(IWingPlugin::RegisteredEvent::ScriptUnSafeFnRegistering)) {
|
||||
registerUnSafeFns(plg);
|
||||
}
|
||||
}
|
||||
|
||||
void PluginSystem::applyFunctionTables(QObject *plg, const CallTable &fns) {
|
||||
|
@ -4050,146 +3857,6 @@ void PluginSystem::applyFunctionTables(QObject *plg, const CallTable &fns) {
|
|||
plg->setProperty("__CALL_POINTER__", quintptr(this));
|
||||
}
|
||||
|
||||
QString PluginSystem::type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier) {
|
||||
auto isArray = !!(type & WingHex::IWingPlugin::Array);
|
||||
auto isList = !!(type & WingHex::IWingPlugin::List);
|
||||
auto isContainer = isArray || isList;
|
||||
if (isContainer) {
|
||||
if (isArray && isList) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QString retype;
|
||||
bool complexType = false;
|
||||
|
||||
type = IWingPlugin::MetaType(type & WingHex::IWingPlugin::MetaTypeMask);
|
||||
switch (type) {
|
||||
case WingHex::IWingPlugin::Void:
|
||||
retype = QStringLiteral("void");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Bool:
|
||||
retype = QStringLiteral("bool");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Int:
|
||||
retype = QStringLiteral("int");
|
||||
break;
|
||||
case WingHex::IWingPlugin::UInt:
|
||||
retype = QStringLiteral("uint");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Int8:
|
||||
retype = QStringLiteral("int8");
|
||||
break;
|
||||
case WingHex::IWingPlugin::UInt8:
|
||||
retype = QStringLiteral("uint8");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Int16:
|
||||
retype = QStringLiteral("int16");
|
||||
break;
|
||||
case WingHex::IWingPlugin::UInt16:
|
||||
retype = QStringLiteral("uint16");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Int64:
|
||||
retype = QStringLiteral("int64");
|
||||
break;
|
||||
case WingHex::IWingPlugin::UInt64:
|
||||
retype = QStringLiteral("uint64");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Float:
|
||||
retype = QStringLiteral("float");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Double:
|
||||
retype = QStringLiteral("double");
|
||||
break;
|
||||
case WingHex::IWingPlugin::String:
|
||||
retype = QStringLiteral("string");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Char:
|
||||
retype = QStringLiteral("char");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Byte:
|
||||
retype = QStringLiteral("byte");
|
||||
break;
|
||||
case WingHex::IWingPlugin::Color:
|
||||
retype = QStringLiteral("color");
|
||||
complexType = true;
|
||||
break;
|
||||
case WingHex::IWingPlugin::Map:
|
||||
case WingHex::IWingPlugin::Hash:
|
||||
retype = QStringLiteral("dictionary");
|
||||
complexType = true;
|
||||
break;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
if (isArray || isList) {
|
||||
retype.append(QStringLiteral("[]"));
|
||||
}
|
||||
|
||||
if (isArg) {
|
||||
if (!noModifier && (isContainer || complexType)) {
|
||||
retype.append(QStringLiteral(" &in"))
|
||||
.prepend(QStringLiteral("const "));
|
||||
}
|
||||
} else {
|
||||
if (!noModifier) {
|
||||
// if it's a return type, only array<byte> and array<string> are
|
||||
// supported in AngelScript
|
||||
// ( array<byte> -> QByteArray , array<string> -> QStringList ),
|
||||
// other array types are not suported. PRs are welcomed !!!
|
||||
// IT'S TOO COMPLEX TO SUPPORT QVARIANTLIST !!!
|
||||
|
||||
// You can use unsafe registering to support
|
||||
// extensive scripting system.
|
||||
// It will be faster and flexible but not easy to implement.
|
||||
if (isContainer) {
|
||||
if (type != WingHex::IWingPlugin::Byte &&
|
||||
type != WingHex::IWingPlugin::String) {
|
||||
return {};
|
||||
}
|
||||
|
||||
retype.append(QStringLiteral("@"));
|
||||
}
|
||||
|
||||
if (complexType) {
|
||||
retype.append(QStringLiteral("@"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retype.trimmed();
|
||||
}
|
||||
|
||||
QString PluginSystem::getScriptFnSig(const QString &fnName,
|
||||
const IWingPlugin::ScriptFnInfo &fninfo) {
|
||||
if (fnName.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString sig;
|
||||
|
||||
auto ret = type2AngelScriptString(fninfo.ret, false);
|
||||
if (ret.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
sig += ret + QStringLiteral(" ") + fnName + QStringLiteral("(");
|
||||
|
||||
QStringList params;
|
||||
for (auto ¶m : fninfo.params) {
|
||||
auto ret = type2AngelScriptString(param.first, true);
|
||||
if (ret.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
params << ret + QStringLiteral(" ") + param.second;
|
||||
}
|
||||
|
||||
return sig + params.join(',') + QStringLiteral(")");
|
||||
}
|
||||
|
||||
QString PluginSystem::getPUID(IWingPluginBase *p) {
|
||||
if (p) {
|
||||
return PluginSystem::instance().getPluginID(p);
|
||||
|
@ -4251,6 +3918,8 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
|
|||
_loadedplgs.append(p);
|
||||
_pinfos.insert(p, meta);
|
||||
|
||||
registerPluginDetectMarco(meta.id);
|
||||
|
||||
Logger::info(tr("PluginName :") + p->pluginName());
|
||||
Logger::debug(tr("PluginAuthor :") + meta.author);
|
||||
Logger::debug(tr("PluginWidgetRegister"));
|
||||
|
@ -4276,9 +3945,6 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
|
|||
registeredSettingPages(QVariant::fromValue(p),
|
||||
p->registeredSettingPages());
|
||||
|
||||
registerFns(p);
|
||||
registerEnums(p);
|
||||
registerMarcos(p);
|
||||
registerEvents(p);
|
||||
|
||||
// prepare for file contenxt
|
||||
|
@ -4320,8 +3986,7 @@ void PluginSystem::loadPlugin(IWingDevice *p, PluginInfo &meta,
|
|||
|
||||
_loadeddevs.append(p);
|
||||
_pinfos.insert(p, meta);
|
||||
|
||||
registerMarcoDevice(p);
|
||||
registerPluginDetectMarco(meta.id);
|
||||
|
||||
// ok register into menu open
|
||||
auto menu =
|
||||
|
@ -4448,12 +4113,6 @@ void PluginSystem::registerPluginDockWidgets(IWingPluginBase *p) {
|
|||
}
|
||||
}
|
||||
|
||||
void PluginSystem::registerMarcoDevice(IWingDevice *plg) {
|
||||
auto id = getPUID(plg).toUpper();
|
||||
auto sep = QStringLiteral("_");
|
||||
_scriptMarcos.append(sep + id + sep);
|
||||
}
|
||||
|
||||
void PluginSystem::registerRibbonTools(
|
||||
const QList<WingRibbonToolBoxInfo> &tools) {
|
||||
if (!tools.isEmpty()) {
|
||||
|
@ -4557,15 +4216,13 @@ void PluginSystem::loadAllPlugin() {
|
|||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(angelapi);
|
||||
auto meta = parsePluginMetadata(doc.object());
|
||||
Q_ASSERT(checkPluginMetadata(meta, true) == PluginStatus::Valid);
|
||||
retranslateMetadata(_angelplg, meta);
|
||||
loadPlugin(_angelplg, meta, std::nullopt);
|
||||
}
|
||||
|
||||
Logger::newLine();
|
||||
|
||||
// ok, setup checking engine
|
||||
initCheckingEngine();
|
||||
|
||||
{
|
||||
QFile cstructjson(QStringLiteral(
|
||||
":/com.wingsummer.winghex/src/class/WingCStruct.json"));
|
||||
|
@ -4577,9 +4234,11 @@ void PluginSystem::loadAllPlugin() {
|
|||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(cstruct);
|
||||
auto meta = parsePluginMetadata(doc.object());
|
||||
Q_ASSERT(checkPluginMetadata(meta, true) == PluginStatus::Valid);
|
||||
|
||||
// internal plugin has no filename
|
||||
if (_manager->onLoadingPlugin({}, meta)) {
|
||||
if (_manager == nullptr ||
|
||||
(_manager && _manager->onLoadingPlugin({}, meta))) {
|
||||
auto cstructplg = new WingCStruct;
|
||||
QDir setd(Utilities::getAppDataPath());
|
||||
auto plgset = QStringLiteral("plgset");
|
||||
|
@ -4626,9 +4285,6 @@ void PluginSystem::loadAllPlugin() {
|
|||
}
|
||||
|
||||
Logger::newLine();
|
||||
|
||||
// loading finished, delete the checking engine
|
||||
finalizeCheckingEngine();
|
||||
}
|
||||
|
||||
void PluginSystem::destory() {
|
||||
|
|
|
@ -136,6 +136,8 @@ public:
|
|||
void loadAllPlugin();
|
||||
void unloadAllPlugin();
|
||||
|
||||
void doneRegisterScriptObj();
|
||||
|
||||
void destory();
|
||||
|
||||
const QList<IWingPlugin *> &plugins() const;
|
||||
|
@ -167,9 +169,6 @@ public:
|
|||
|
||||
static QString getPUID(IWingPluginBase *p);
|
||||
|
||||
static QString type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier = false);
|
||||
|
||||
private:
|
||||
void loadExtPlugin();
|
||||
|
||||
|
@ -207,22 +206,13 @@ private:
|
|||
|
||||
PluginStatus checkPluginMetadata(const PluginInfo &meta, bool isPlg);
|
||||
|
||||
static bool isValidIdentifier(const QString &str);
|
||||
|
||||
void retranslateMetadata(IWingPluginBase *plg, PluginInfo &meta);
|
||||
|
||||
private:
|
||||
void registerFns(IWingPlugin *plg);
|
||||
void registerUnSafeFns(IWingPlugin *plg);
|
||||
void registerEnums(IWingPlugin *plg);
|
||||
void registerMarcos(IWingPlugin *plg);
|
||||
void registerEvents(IWingPlugin *plg);
|
||||
|
||||
void applyFunctionTables(QObject *plg, const CallTable &fns);
|
||||
|
||||
static QString getScriptFnSig(const QString &fnName,
|
||||
const IWingPlugin::ScriptFnInfo &fninfo);
|
||||
|
||||
bool isPluginLoaded(const WingDependency &d);
|
||||
|
||||
bool isPluginLoaded(const QString &id);
|
||||
|
@ -245,7 +235,7 @@ private:
|
|||
const std::optional<QDir> &setdir);
|
||||
|
||||
private:
|
||||
void registerMarcoDevice(IWingDevice *plg);
|
||||
void registerPluginDetectMarco(const QString &id);
|
||||
|
||||
private:
|
||||
void registerRibbonTools(const QList<WingRibbonToolBoxInfo> &tools);
|
||||
|
@ -319,10 +309,6 @@ private:
|
|||
PluginSystem(QObject *parent = nullptr);
|
||||
~PluginSystem();
|
||||
|
||||
void initCheckingEngine();
|
||||
|
||||
void finalizeCheckingEngine();
|
||||
|
||||
// IWingPluginBase API
|
||||
public slots:
|
||||
WING_API void toast(const QObject *sender, const QPixmap &icon,
|
||||
|
@ -712,6 +698,14 @@ public slots:
|
|||
// extension
|
||||
WING_API bool closeAllFiles(const QObject *sender);
|
||||
|
||||
// generic call support
|
||||
WING_API WingHex::IWingGeneric *__createParamContext(const QObject *sender,
|
||||
void *ctx);
|
||||
|
||||
WING_API void __raiseContextException(const QObject *sender,
|
||||
const QString &exception,
|
||||
bool allowCatch = true);
|
||||
|
||||
private:
|
||||
WingHex::IWingPlugin *checkPluginAndReport(const QObject *sender,
|
||||
const char *func);
|
||||
|
@ -742,13 +736,10 @@ private:
|
|||
|
||||
UniqueIdGenerator m_idGen;
|
||||
|
||||
QHash<QString, QHash<QString, WingAngelAPI::ScriptFnInfo>> _scfns;
|
||||
|
||||
IWingManager *_manager = nullptr;
|
||||
std::optional<PluginInfo> _manInfo;
|
||||
|
||||
WingAngelAPI *_angelplg = nullptr;
|
||||
asCScriptEngine *_engine = nullptr;
|
||||
|
||||
QStringList _scriptMarcos;
|
||||
QList<IWingPlugin *> _pragmaedPlg;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "AngelScript/sdk/add_on/scriptmath/scriptmath.h"
|
||||
#include "AngelScript/sdk/add_on/scriptmath/scriptmathcomplex.h"
|
||||
#include "AngelScript/sdk/add_on/weakref/weakref.h"
|
||||
#include "AngelScript/sdk/angelscript/source/as_scriptengine.h"
|
||||
|
||||
#include "angelobjstring.h"
|
||||
#include "class/appmanager.h"
|
||||
|
@ -145,6 +146,16 @@ bool ScriptMachine::isRunning(ConsoleMode mode) const {
|
|||
return _ctx.value(mode) != nullptr;
|
||||
}
|
||||
|
||||
bool ScriptMachine::isEngineConfigError() const {
|
||||
if (_engine) {
|
||||
auto e = dynamic_cast<asCScriptEngine *>(_engine);
|
||||
if (e) {
|
||||
return e->configFailed;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define INS_1 "const ?&in = null"
|
||||
#define INS_2 INS_1 ", " INS_1
|
||||
#define INS_4 INS_2 ", " INS_2
|
||||
|
|
|
@ -116,6 +116,7 @@ public:
|
|||
bool init();
|
||||
bool isInited() const;
|
||||
bool isRunning(ConsoleMode mode) const;
|
||||
bool isEngineConfigError() const;
|
||||
|
||||
static void registerEngineAddon(asIScriptEngine *engine);
|
||||
static void registerEngineAssert(asIScriptEngine *engine);
|
||||
|
@ -150,15 +151,15 @@ public:
|
|||
bool isDebugMode(ConsoleMode mode = Scripting);
|
||||
|
||||
public slots:
|
||||
bool executeCode(ConsoleMode mode, const QString &code);
|
||||
bool executeCode(ScriptMachine::ConsoleMode mode, const QString &code);
|
||||
// only scripting mode can be debugged
|
||||
bool executeScript(ConsoleMode mode, const QString &script,
|
||||
bool executeScript(ScriptMachine::ConsoleMode mode, const QString &script,
|
||||
bool isInDebug = false, int *retCode = nullptr);
|
||||
|
||||
int evaluateDefine(const QString &code, bool &result);
|
||||
|
||||
void abortDbgScript();
|
||||
void abortScript(ConsoleMode mode);
|
||||
void abortScript(ScriptMachine::ConsoleMode mode);
|
||||
void abortScript();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define SKINMANAGER_H
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
|
||||
class SkinManager {
|
||||
|
|
|
@ -0,0 +1,597 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** 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 Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "wingangel.h"
|
||||
#include "define.h"
|
||||
#include "wingangelapi.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include "scriptmachine.h"
|
||||
#include "utilities.h"
|
||||
|
||||
inline asSFuncPtr asCSFuncPtr(const WingHex::asFuncPtr &ptr) {
|
||||
// some checks
|
||||
static_assert(std::is_standard_layout_v<asSFuncPtr>,
|
||||
"asSFuncPtr must be standard layout");
|
||||
static_assert(std::is_standard_layout_v<WingHex::asFuncPtr>,
|
||||
"WingHex::asFuncPtr must be standard layout");
|
||||
static_assert(sizeof(asSFuncPtr) == sizeof(WingHex::asFuncPtr),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(alignof(asSFuncPtr) == alignof(WingHex::asFuncPtr),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(offsetof(asSFuncPtr, ptr) ==
|
||||
offsetof(WingHex::asFuncPtr, ptr),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(offsetof(asSFuncPtr, flag) ==
|
||||
offsetof(WingHex::asFuncPtr, flag),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(sizeof(asSFuncPtr::ptr) == sizeof(WingHex::asFuncPtr::ptr),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(std::is_same_v<decltype(asSFuncPtr::flag),
|
||||
decltype(WingHex::asFuncPtr::flag)>,
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(offsetof(asSFuncPtr, flag) ==
|
||||
offsetof(WingHex::asFuncPtr, flag),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
|
||||
using StructM = decltype(std::declval<asSFuncPtr>().ptr.m);
|
||||
using StructF = decltype(std::declval<asSFuncPtr>().ptr.f);
|
||||
|
||||
using wStructM = decltype(std::declval<WingHex::asFuncPtr>().ptr.m);
|
||||
using wStructF = decltype(std::declval<WingHex::asFuncPtr>().ptr.f);
|
||||
|
||||
static_assert(offsetof(StructM, mthd) == offsetof(wStructM, mthd),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(offsetof(StructF, func) == offsetof(wStructF, func),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(offsetof(StructM, dummy) == offsetof(wStructM, dummy),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(offsetof(StructF, dummy) == offsetof(wStructF, dummy),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(sizeof(StructM::mthd) == sizeof(wStructM::mthd),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(sizeof(StructF::func) == sizeof(wStructF::func),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(sizeof(StructM::dummy) == sizeof(wStructM::dummy),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
static_assert(sizeof(StructF::dummy) == sizeof(wStructF::dummy),
|
||||
"asSFuncPtr is not same as WingHex::asFuncPtr");
|
||||
|
||||
// just so simple
|
||||
asSFuncPtr ret;
|
||||
std::memcpy(&ret, &ptr, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// some checks
|
||||
static_assert(asEBehaviours::asBEHAVE_CONSTRUCT ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_CONSTRUCT),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_LIST_CONSTRUCT ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_LIST_CONSTRUCT),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_DESTRUCT ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_DESTRUCT),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_FACTORY ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_FACTORY),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_LIST_FACTORY ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_LIST_FACTORY),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_ADDREF ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_ADDREF),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_RELEASE ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_RELEASE),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_GET_WEAKREF_FLAG ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_GET_WEAKREF_FLAG),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_TEMPLATE_CALLBACK ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_TEMPLATE_CALLBACK),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_FIRST_GC ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_FIRST_GC),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_GETREFCOUNT ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_GETREFCOUNT),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_SETGCFLAG ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_SETGCFLAG),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_GETGCFLAG ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_GETGCFLAG),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_ENUMREFS ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_ENUMREFS),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_RELEASEREFS ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_RELEASEREFS),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_LAST_GC ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_LAST_GC),
|
||||
"asEBehaviours check failed");
|
||||
static_assert(asEBehaviours::asBEHAVE_RELEASEREFS ==
|
||||
int(WingHex::IWingAngel::asBEHAVE_RELEASEREFS),
|
||||
"asEBehaviours check failed");
|
||||
|
||||
static_assert(asERetCodes::asSUCCESS == int(WingHex::asRetCodes::asSUCCESS),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asERROR == int(WingHex::asRetCodes::asERROR),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asCONTEXT_ACTIVE ==
|
||||
int(WingHex::asRetCodes::asCONTEXT_ACTIVE),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asCONTEXT_NOT_FINISHED ==
|
||||
int(WingHex::asRetCodes::asCONTEXT_NOT_FINISHED),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asCONTEXT_NOT_PREPARED ==
|
||||
int(WingHex::asRetCodes::asCONTEXT_NOT_PREPARED),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_ARG ==
|
||||
int(WingHex::asRetCodes::asINVALID_ARG),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asNO_FUNCTION ==
|
||||
int(WingHex::asRetCodes::asNO_FUNCTION),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asNOT_SUPPORTED ==
|
||||
int(WingHex::asRetCodes::asNOT_SUPPORTED),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_NAME ==
|
||||
int(WingHex::asRetCodes::asINVALID_NAME),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asNAME_TAKEN ==
|
||||
int(WingHex::asRetCodes::asNAME_TAKEN),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_DECLARATION ==
|
||||
int(WingHex::asRetCodes::asINVALID_DECLARATION),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_OBJECT ==
|
||||
int(WingHex::asRetCodes::asINVALID_OBJECT),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_TYPE ==
|
||||
int(WingHex::asRetCodes::asINVALID_TYPE),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asALREADY_REGISTERED ==
|
||||
int(WingHex::asRetCodes::asALREADY_REGISTERED),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asMULTIPLE_FUNCTIONS ==
|
||||
int(WingHex::asRetCodes::asMULTIPLE_FUNCTIONS),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asNO_MODULE == int(WingHex::asRetCodes::asNO_MODULE),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asNO_GLOBAL_VAR ==
|
||||
int(WingHex::asRetCodes::asNO_GLOBAL_VAR),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_CONFIGURATION ==
|
||||
int(WingHex::asRetCodes::asINVALID_CONFIGURATION),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINVALID_INTERFACE ==
|
||||
int(WingHex::asRetCodes::asINVALID_INTERFACE),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asCANT_BIND_ALL_FUNCTIONS ==
|
||||
int(WingHex::asRetCodes::asCANT_BIND_ALL_FUNCTIONS),
|
||||
"asERetCodes check failed");
|
||||
static_assert(
|
||||
asERetCodes::asLOWER_ARRAY_DIMENSION_NOT_REGISTERED ==
|
||||
int(WingHex::asRetCodes::asLOWER_ARRAY_DIMENSION_NOT_REGISTERED),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asWRONG_CONFIG_GROUP ==
|
||||
int(WingHex::asRetCodes::asWRONG_CONFIG_GROUP),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asCONFIG_GROUP_IS_IN_USE ==
|
||||
int(WingHex::asRetCodes::asCONFIG_GROUP_IS_IN_USE),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asILLEGAL_BEHAVIOUR_FOR_TYPE ==
|
||||
int(WingHex::asRetCodes::asILLEGAL_BEHAVIOUR_FOR_TYPE),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asWRONG_CALLING_CONV ==
|
||||
int(WingHex::asRetCodes::asWRONG_CALLING_CONV),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asBUILD_IN_PROGRESS ==
|
||||
int(WingHex::asRetCodes::asBUILD_IN_PROGRESS),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asINIT_GLOBAL_VARS_FAILED ==
|
||||
int(WingHex::asRetCodes::asINIT_GLOBAL_VARS_FAILED),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asOUT_OF_MEMORY ==
|
||||
int(WingHex::asRetCodes::asOUT_OF_MEMORY),
|
||||
"asERetCodes check failed");
|
||||
static_assert(asERetCodes::asMODULE_IS_IN_USE ==
|
||||
int(WingHex::asRetCodes::asMODULE_IS_IN_USE),
|
||||
"asERetCodes check failed");
|
||||
|
||||
WingAngel::WingAngel(WingAngelAPI *api, QStringList &marcos)
|
||||
: _api(api), _scriptMarcos(marcos) {
|
||||
Q_ASSERT(api);
|
||||
}
|
||||
|
||||
bool WingAngel::setCurrentPluginSession(const QByteArray &ns) {
|
||||
if (ns != _plgsess) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->SetDefaultNamespace(ns.data());
|
||||
if (ret != asSUCCESS) {
|
||||
return false;
|
||||
}
|
||||
_plgsess = ns;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WingHex::asRetCodes
|
||||
WingAngel::registerGlobalFunction(uint retMetaType, const ScriptFn &fn,
|
||||
const QString &fnName,
|
||||
const QVector<QPair<uint, QString>> ¶ms) {
|
||||
auto sig = getScriptFnSig(retMetaType, fn, fnName, params);
|
||||
if (sig.isEmpty()) {
|
||||
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + _plgsess +
|
||||
QStringLiteral("::") + fnName);
|
||||
return WingHex::asRetCodes::asINVALID_ARG;
|
||||
}
|
||||
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
|
||||
auto ret = engine->RegisterGlobalFunction(
|
||||
sig.toUtf8(), asFUNCTION(WingAngelAPI::script_call),
|
||||
asECallConvTypes::asCALL_GENERIC);
|
||||
|
||||
if (ret < 0) {
|
||||
// TODO
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
auto &sfns = _api->_sfns;
|
||||
auto id = sfns.size();
|
||||
|
||||
auto f = engine->GetFunctionById(ret);
|
||||
if (f) {
|
||||
f->SetUserData(_api, AsUserDataType::UserData_API);
|
||||
f->SetUserData(reinterpret_cast<void *>(id),
|
||||
AsUserDataType::UserData_PluginFn);
|
||||
} else {
|
||||
return WingHex::asRetCodes::asINVALID_ARG;
|
||||
}
|
||||
|
||||
WingScriptInternal::ScriptFnInfo info;
|
||||
info.ret = retMetaType;
|
||||
info.fn = fn;
|
||||
info.params = params;
|
||||
|
||||
sfns.append(info);
|
||||
|
||||
return WingHex::asRetCodes::asSUCCESS;
|
||||
}
|
||||
|
||||
WingHex::asRetCodes
|
||||
WingAngel::registerGlobalFunction(const QString &decl,
|
||||
const WingHex::UNSAFE_SCFNPTR &fn) {
|
||||
if (decl.isEmpty()) {
|
||||
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + _plgsess +
|
||||
QStringLiteral("::") + decl);
|
||||
return WingHex::asRetCodes::asINVALID_ARG;
|
||||
}
|
||||
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
|
||||
auto ret = engine->RegisterGlobalFunction(
|
||||
decl.toUtf8(), asFUNCTION(WingAngelAPI::script_unsafe_call),
|
||||
asECallConvTypes::asCALL_GENERIC);
|
||||
|
||||
if (ret < 0) {
|
||||
// TODO
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
auto &sfns = _api->_usfns;
|
||||
auto id = sfns.size();
|
||||
|
||||
auto f = engine->GetFunctionById(ret);
|
||||
if (f) {
|
||||
f->SetUserData(_api, AsUserDataType::UserData_API);
|
||||
f->SetUserData(reinterpret_cast<void *>(id),
|
||||
AsUserDataType::UserData_PluginFn);
|
||||
} else {
|
||||
return WingHex::asRetCodes::asINVALID_ARG;
|
||||
}
|
||||
|
||||
sfns.append(fn);
|
||||
|
||||
return WingHex::asRetCodes::asSUCCESS;
|
||||
}
|
||||
|
||||
void WingAngel::registerScriptMarco(const QString &marco) {
|
||||
if (Utilities::isValidIdentifier(marco)) {
|
||||
static auto sep = QStringLiteral("_");
|
||||
_scriptMarcos.append(sep + _plgsess + sep + marco + sep);
|
||||
} else {
|
||||
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
void WingAngel::registerScriptMarcos(const QStringList &marcos) {
|
||||
for (auto &m : marcos) {
|
||||
registerScriptMarco(m);
|
||||
}
|
||||
}
|
||||
|
||||
WingHex::asRetCodes
|
||||
WingAngel::registerGlobalFunction(const char *declaration,
|
||||
const WingHex::asFuncPtr &funcPointer,
|
||||
asCallConvTypes callConv, void *auxiliary) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterGlobalFunction(
|
||||
declaration, asCSFuncPtr(funcPointer), asDWORD(callConv), auxiliary);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes
|
||||
WingAngel::registerInterfaceMethod(const char *intf, const char *declaration) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterInterfaceMethod(intf, declaration);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerInterface(const char *name) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterInterface(name);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerObjectBehaviour(
|
||||
const char *obj, asBehaviours behaviour, const char *declaration,
|
||||
const WingHex::asFuncPtr &funcPointer, asCallConvTypes callConv,
|
||||
void *auxiliary, int compositeOffset, bool isCompositeIndirect) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterObjectBehaviour(
|
||||
obj, asEBehaviours(behaviour), declaration, asCSFuncPtr(funcPointer),
|
||||
asECallConvTypes(callConv), auxiliary, compositeOffset,
|
||||
isCompositeIndirect);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes
|
||||
WingAngel::registerObjectMethod(const char *obj, const char *declaration,
|
||||
const WingHex::asFuncPtr &funcPointer,
|
||||
asCallConvTypes callConv, void *auxiliary,
|
||||
int compositeOffset, bool isCompositeIndirect) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterObjectMethod(
|
||||
obj, declaration, asCSFuncPtr(funcPointer), asECallConvTypes(callConv),
|
||||
auxiliary, compositeOffset, isCompositeIndirect);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes
|
||||
WingAngel::registerObjectProperty(const char *obj, const char *declaration,
|
||||
int byteOffset, int compositeOffset,
|
||||
bool isCompositeIndirect) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterObjectProperty(
|
||||
obj, declaration, byteOffset, compositeOffset, isCompositeIndirect);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerObjectType(const char *obj, int byteSize,
|
||||
quint64 flags) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterObjectType(obj, byteSize, flags);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerGlobalProperty(const char *declaration,
|
||||
void *pointer) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterGlobalProperty(declaration, pointer);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerTypedef(const char *type,
|
||||
const char *decl) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterTypedef(type, decl);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerFuncdef(const char *decl) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterFuncdef(decl);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerEnumValue(const char *type,
|
||||
const char *name, int value) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterEnumValue(type, name, value);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::registerEnum(const char *type) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->RegisterEnum(type);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::restoreDefaultNamespace() {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto ret = engine->SetDefaultNamespace(_plgsess);
|
||||
return returnValue(ret);
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::setDefaultNamespace(const char *nameSpace) {
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
if (nameSpace) {
|
||||
if (qstrlen(nameSpace) > 1024) {
|
||||
return WingHex::asRetCodes::asINVALID_NAME;
|
||||
}
|
||||
auto ns = _plgsess.append(QByteArrayLiteral("::")).append(nameSpace);
|
||||
auto ret = engine->SetDefaultNamespace(ns.data());
|
||||
return returnValue(ret);
|
||||
} else {
|
||||
return restoreDefaultNamespace();
|
||||
}
|
||||
}
|
||||
|
||||
QString WingAngel::getScriptFnSig(uint retMetaType, const ScriptFn &fn,
|
||||
const QString &fnName,
|
||||
const QVector<QPair<uint, QString>> ¶ms) {
|
||||
if (fnName.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString sig;
|
||||
|
||||
auto ret = type2AngelScriptString(retMetaType, false);
|
||||
if (ret.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
sig += ret + QStringLiteral(" ") + fnName + QStringLiteral("(");
|
||||
|
||||
QStringList _params;
|
||||
for (auto ¶m : params) {
|
||||
auto ret = type2AngelScriptString(param.first, true);
|
||||
if (ret.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
_params << ret + QStringLiteral(" ") + param.second;
|
||||
}
|
||||
|
||||
return sig + _params.join(',') + QStringLiteral(")");
|
||||
}
|
||||
|
||||
QString WingAngel::type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier) {
|
||||
auto isArray = !!(type & WingHex::Meta_Array);
|
||||
auto isList = !!(type & WingHex::Meta_List);
|
||||
auto isContainer = isArray || isList;
|
||||
if (isContainer) {
|
||||
if (isArray && isList) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QString retype;
|
||||
bool complexType = false;
|
||||
|
||||
type = WingHex::MetaType(type & WingHex::MetaTypeMask);
|
||||
switch (type) {
|
||||
case WingHex::Meta_Void:
|
||||
retype = QStringLiteral("void");
|
||||
break;
|
||||
case WingHex::Meta_Bool:
|
||||
retype = QStringLiteral("bool");
|
||||
break;
|
||||
case WingHex::Meta_Int:
|
||||
retype = QStringLiteral("int");
|
||||
break;
|
||||
case WingHex::Meta_UInt:
|
||||
retype = QStringLiteral("uint");
|
||||
break;
|
||||
case WingHex::Meta_Int8:
|
||||
retype = QStringLiteral("int8");
|
||||
break;
|
||||
case WingHex::Meta_UInt8:
|
||||
retype = QStringLiteral("uint8");
|
||||
break;
|
||||
case WingHex::Meta_Int16:
|
||||
retype = QStringLiteral("int16");
|
||||
break;
|
||||
case WingHex::Meta_UInt16:
|
||||
retype = QStringLiteral("uint16");
|
||||
break;
|
||||
case WingHex::Meta_Int64:
|
||||
retype = QStringLiteral("int64");
|
||||
break;
|
||||
case WingHex::Meta_UInt64:
|
||||
retype = QStringLiteral("uint64");
|
||||
break;
|
||||
case WingHex::Meta_Float:
|
||||
retype = QStringLiteral("float");
|
||||
break;
|
||||
case WingHex::Meta_Double:
|
||||
retype = QStringLiteral("double");
|
||||
break;
|
||||
case WingHex::Meta_String:
|
||||
retype = QStringLiteral("string");
|
||||
break;
|
||||
case WingHex::Meta_Char:
|
||||
retype = QStringLiteral("char");
|
||||
break;
|
||||
case WingHex::Meta_Byte:
|
||||
retype = QStringLiteral("byte");
|
||||
break;
|
||||
case WingHex::Meta_Color:
|
||||
retype = QStringLiteral("color");
|
||||
complexType = true;
|
||||
break;
|
||||
case WingHex::Meta_Map:
|
||||
case WingHex::Meta_Hash:
|
||||
retype = QStringLiteral("dictionary");
|
||||
complexType = true;
|
||||
break;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
if (isArray || isList) {
|
||||
retype.append(QStringLiteral("[]"));
|
||||
}
|
||||
|
||||
if (isArg) {
|
||||
if (!noModifier && (isContainer || complexType)) {
|
||||
retype.append(QStringLiteral(" &in"))
|
||||
.prepend(QStringLiteral("const "));
|
||||
}
|
||||
} else {
|
||||
if (!noModifier) {
|
||||
// if it's a return type, only array<byte> and array<string> are
|
||||
// supported in AngelScript
|
||||
// ( array<byte> -> QByteArray , array<string> -> QStringList ),
|
||||
// other array types are not suported. PRs are welcomed !!!
|
||||
// IT'S TOO COMPLEX TO SUPPORT QVARIANTLIST !!!
|
||||
|
||||
// You can use unsafe registering to support
|
||||
// extensive scripting system.
|
||||
// It will be faster and flexible but not easy to implement.
|
||||
if (isContainer) {
|
||||
if (type != WingHex::Meta_Byte &&
|
||||
type != WingHex::Meta_String) {
|
||||
return {};
|
||||
}
|
||||
|
||||
retype.append(QStringLiteral("@"));
|
||||
}
|
||||
|
||||
if (complexType) {
|
||||
retype.append(QStringLiteral("@"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retype.trimmed();
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingAngel::returnValue(int ret) {
|
||||
if (ret < 0) {
|
||||
return WingHex::asRetCodes(ret);
|
||||
} else {
|
||||
return WingHex::asRetCodes::asSUCCESS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** 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 Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef WINGANGEL_H
|
||||
#define WINGANGEL_H
|
||||
|
||||
#include "WingPlugin/iwingangel.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class WingAngelAPI;
|
||||
|
||||
class WingAngel : public WingHex::IWingAngel {
|
||||
Q_DECLARE_TR_FUNCTIONS(WingAngel)
|
||||
|
||||
public:
|
||||
WingAngel(WingAngelAPI *api, QStringList &marcos);
|
||||
|
||||
public:
|
||||
bool setCurrentPluginSession(const QByteArray &ns);
|
||||
|
||||
// IWingAngel interface
|
||||
public:
|
||||
virtual WingHex::asRetCodes registerGlobalFunction(
|
||||
uint retMetaType, const ScriptFn &fn, const QString &fnName,
|
||||
const QVector<QPair<uint, QString>> ¶ms) override;
|
||||
|
||||
virtual WingHex::asRetCodes
|
||||
registerGlobalFunction(const QString &decl,
|
||||
const WingHex::UNSAFE_SCFNPTR &fn) override;
|
||||
|
||||
virtual void registerScriptMarco(const QString &marco) override;
|
||||
virtual void registerScriptMarcos(const QStringList &marcos) override;
|
||||
virtual WingHex::asRetCodes
|
||||
setDefaultNamespace(const char *nameSpace) override;
|
||||
virtual WingHex::asRetCodes restoreDefaultNamespace() override;
|
||||
virtual WingHex::asRetCodes registerEnum(const char *type) override;
|
||||
virtual WingHex::asRetCodes
|
||||
registerEnumValue(const char *type, const char *name, int value) override;
|
||||
virtual WingHex::asRetCodes registerFuncdef(const char *decl) override;
|
||||
virtual WingHex::asRetCodes registerTypedef(const char *type,
|
||||
const char *decl) override;
|
||||
virtual WingHex::asRetCodes registerGlobalProperty(const char *declaration,
|
||||
void *pointer) override;
|
||||
virtual WingHex::asRetCodes
|
||||
registerObjectType(const char *obj, int byteSize, quint64 flags) override;
|
||||
|
||||
virtual WingHex::asRetCodes
|
||||
registerObjectProperty(const char *obj, const char *declaration,
|
||||
int byteOffset, int compositeOffset,
|
||||
bool isCompositeIndirect) override;
|
||||
virtual WingHex::asRetCodes
|
||||
registerObjectMethod(const char *obj, const char *declaration,
|
||||
const WingHex::asFuncPtr &funcPointer,
|
||||
asCallConvTypes callConv, void *auxiliary,
|
||||
int compositeOffset,
|
||||
bool isCompositeIndirect) override;
|
||||
|
||||
virtual WingHex::asRetCodes registerObjectBehaviour(
|
||||
const char *obj, asBehaviours behaviour, const char *declaration,
|
||||
const WingHex::asFuncPtr &funcPointer, asCallConvTypes callConv,
|
||||
void *auxiliary, int compositeOffset,
|
||||
bool isCompositeIndirect) override;
|
||||
|
||||
virtual WingHex::asRetCodes registerInterface(const char *name) override;
|
||||
|
||||
virtual WingHex::asRetCodes
|
||||
registerInterfaceMethod(const char *intf, const char *declaration) override;
|
||||
|
||||
virtual WingHex::asRetCodes
|
||||
registerGlobalFunction(const char *declaration,
|
||||
const WingHex::asFuncPtr &funcPointer,
|
||||
asCallConvTypes callConv, void *auxiliary) override;
|
||||
|
||||
private:
|
||||
static QString getScriptFnSig(uint retMetaType, const ScriptFn &fn,
|
||||
const QString &fnName,
|
||||
const QVector<QPair<uint, QString>> ¶ms);
|
||||
|
||||
static QString type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier = false);
|
||||
|
||||
private:
|
||||
WingHex::asRetCodes returnValue(int ret);
|
||||
|
||||
private:
|
||||
WingAngelAPI *_api;
|
||||
QByteArray _plgsess;
|
||||
|
||||
QStringList &_scriptMarcos;
|
||||
};
|
||||
|
||||
#endif // WINGANGEL_H
|
|
@ -18,9 +18,9 @@
|
|||
#include "wingangelapi.h"
|
||||
|
||||
#include "AngelScript/sdk/angelscript/include/angelscript.h"
|
||||
#include "WingPlugin/iwingangel.h"
|
||||
#include "class/angelscripthelper.h"
|
||||
#include "class/logger.h"
|
||||
#include "class/pluginsystem.h"
|
||||
#include "class/scriptmachine.h"
|
||||
#include "class/wingfiledialog.h"
|
||||
#include "class/winginputdialog.h"
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include <QJsonDocument>
|
||||
#include <QMessageBox>
|
||||
#include <QTemporaryFile>
|
||||
#include <QThread>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#undef MessageBox
|
||||
|
@ -67,8 +68,8 @@ QString WingAngelAPI::retranslate(const QString &str) {
|
|||
return QApplication::tr(str.toLatin1());
|
||||
}
|
||||
|
||||
QStringList WingAngelAPI::registerScriptMarcos() const {
|
||||
return {"EXEC_BASE", "AS_ARRAY_EXT", "AS_DICTIONARY_EXT"};
|
||||
void WingAngelAPI::onRegisterScriptObj(WingHex::IWingAngel *o) {
|
||||
o->registerScriptMarcos({"EXEC_BASE", "AS_ARRAY_EXT", "AS_DICTIONARY_EXT"});
|
||||
}
|
||||
|
||||
WingHex::IWingPlugin::RegisteredEvents WingAngelAPI::registeredEvents() const {
|
||||
|
@ -91,48 +92,6 @@ void WingAngelAPI::eventPluginFile(PluginFileEvent e, FileType type,
|
|||
}
|
||||
}
|
||||
|
||||
void WingAngelAPI::registerUnSafeScriptFns(
|
||||
const QString &ns, const QHash<QString, UNSAFE_SCFNPTR> &rfns) {
|
||||
Q_ASSERT(!ns.isEmpty());
|
||||
if (rfns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto id = _usfns.size();
|
||||
for (auto p = rfns.constKeyValueBegin(); p != rfns.constKeyValueEnd();
|
||||
p++) {
|
||||
_urfns[ns][p->first] = id;
|
||||
id++;
|
||||
_usfns.append(p->second);
|
||||
}
|
||||
}
|
||||
|
||||
void WingAngelAPI::registerScriptEnums(
|
||||
const QString &ns, const QHash<QString, QList<QPair<QString, int>>> &objs) {
|
||||
Q_ASSERT(!ns.isEmpty());
|
||||
if (objs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_objs.insert(ns, objs);
|
||||
}
|
||||
|
||||
void WingAngelAPI::registerScriptFns(const QString &ns,
|
||||
const QHash<QString, ScriptFnInfo> &rfns) {
|
||||
Q_ASSERT(!ns.isEmpty());
|
||||
if (rfns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto id = _sfns.size();
|
||||
for (auto p = rfns.constKeyValueBegin(); p != rfns.constKeyValueEnd();
|
||||
p++) {
|
||||
_rfns[ns][p->first] = id;
|
||||
id++;
|
||||
_sfns.append(p->second);
|
||||
}
|
||||
}
|
||||
|
||||
void WingAngelAPI::installAPI(ScriptMachine *machine) {
|
||||
Q_ASSERT(machine);
|
||||
auto engine = machine->engine();
|
||||
|
@ -148,9 +107,7 @@ void WingAngelAPI::installAPI(ScriptMachine *machine) {
|
|||
installHexReaderAPI(engine);
|
||||
installHexControllerAPI(engine);
|
||||
|
||||
installScriptEnums(engine);
|
||||
installScriptFns(engine);
|
||||
installScriptUnSafeFns(engine);
|
||||
// plugin script objects will be install later
|
||||
}
|
||||
|
||||
void WingAngelAPI::installBasicTypes(asIScriptEngine *engine) {
|
||||
|
@ -1082,89 +1039,6 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
engine->SetDefaultNamespace("");
|
||||
}
|
||||
|
||||
void WingAngelAPI::installScriptFns(asIScriptEngine *engine) {
|
||||
for (auto pfns = _rfns.constKeyValueBegin();
|
||||
pfns != _rfns.constKeyValueEnd(); pfns++) {
|
||||
auto ns = pfns->first;
|
||||
int r = engine->SetDefaultNamespace(ns.toUtf8());
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
|
||||
auto &pfn = pfns->second;
|
||||
for (auto p = pfn.constKeyValueBegin(); p != pfn.constKeyValueEnd();
|
||||
p++) {
|
||||
auto sig = p->first;
|
||||
auto id = p->second;
|
||||
auto r = engine->RegisterGlobalFunction(
|
||||
sig.toUtf8(), asFUNCTION(script_call), asCALL_GENERIC);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
|
||||
// r is the AngelScript function ID
|
||||
auto fn = engine->GetFunctionById(r);
|
||||
fn->SetUserData(this, AsUserDataType::UserData_API);
|
||||
fn->SetUserData(reinterpret_cast<void *>(id),
|
||||
AsUserDataType::UserData_PluginFn);
|
||||
}
|
||||
engine->SetDefaultNamespace("");
|
||||
}
|
||||
}
|
||||
|
||||
void WingAngelAPI::installScriptUnSafeFns(asIScriptEngine *engine) {
|
||||
for (auto pfns = _urfns.constKeyValueBegin();
|
||||
pfns != _urfns.constKeyValueEnd(); pfns++) {
|
||||
auto ns = pfns->first;
|
||||
int r = engine->SetDefaultNamespace(ns.toUtf8());
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
|
||||
auto &pfn = pfns->second;
|
||||
for (auto p = pfn.constKeyValueBegin(); p != pfn.constKeyValueEnd();
|
||||
p++) {
|
||||
auto sig = p->first;
|
||||
auto id = p->second;
|
||||
auto r = engine->RegisterGlobalFunction(
|
||||
sig.toUtf8(), asFUNCTION(script_unsafe_call), asCALL_GENERIC);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
|
||||
// r is the AngelScript function ID
|
||||
auto fn = engine->GetFunctionById(r);
|
||||
fn->SetUserData(this, AsUserDataType::UserData_API);
|
||||
fn->SetUserData(reinterpret_cast<void *>(id),
|
||||
AsUserDataType::UserData_PluginFn);
|
||||
}
|
||||
engine->SetDefaultNamespace("");
|
||||
}
|
||||
}
|
||||
|
||||
void WingAngelAPI::installScriptEnums(asIScriptEngine *engine) {
|
||||
for (auto pobjs = _objs.constKeyValueBegin();
|
||||
pobjs != _objs.constKeyValueEnd(); ++pobjs) {
|
||||
auto ns = pobjs->first;
|
||||
int r = engine->SetDefaultNamespace(ns.toUtf8());
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
|
||||
auto &pobj = pobjs->second;
|
||||
for (auto p = pobj.constKeyValueBegin(); p != pobj.constKeyValueEnd();
|
||||
p++) {
|
||||
auto en = p->first.toUtf8();
|
||||
r = engine->RegisterEnum(en.data());
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
|
||||
for (auto &e : p->second) {
|
||||
auto ev = e.first.toUtf8();
|
||||
r = engine->RegisterEnumValue(en.data(), ev.data(), e.second);
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
}
|
||||
}
|
||||
engine->SetDefaultNamespace("");
|
||||
}
|
||||
}
|
||||
|
||||
void WingAngelAPI::registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn,
|
||||
const char *sig) {
|
||||
auto r =
|
||||
|
@ -1563,12 +1437,13 @@ QVariant WingAngelAPI::qvariantGet(asIScriptEngine *engine, const void *raw,
|
|||
return {};
|
||||
}
|
||||
|
||||
bool WingAngelAPI::getQVariantGetFlag(const ScriptFnInfo &info, int index) {
|
||||
bool WingAngelAPI::getQVariantGetFlag(
|
||||
const WingScriptInternal::ScriptFnInfo &info, int index) {
|
||||
auto ¶ms = info.params;
|
||||
Q_ASSERT(index >= 0 && index < params.size());
|
||||
|
||||
auto minfo = params.at(index).first;
|
||||
return !!(minfo & MetaType::List) || !!(minfo & MetaType::Hash);
|
||||
return !!(minfo & WingHex::Meta_List) || !!(minfo & WingHex::Meta_Hash);
|
||||
}
|
||||
|
||||
int WingAngelAPI::qvariantCastASID(asIScriptEngine *engine,
|
||||
|
@ -1696,6 +1571,118 @@ bool WingAngelAPI::isTempBuffered(QMetaType::Type type) {
|
|||
}
|
||||
}
|
||||
|
||||
QString WingAngelAPI::type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier) {
|
||||
auto isArray = !!(type & WingHex::Meta_Array);
|
||||
auto isList = !!(type & WingHex::Meta_List);
|
||||
auto isContainer = isArray || isList;
|
||||
if (isContainer) {
|
||||
if (isArray && isList) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QString retype;
|
||||
bool complexType = false;
|
||||
|
||||
type = WingHex::MetaType(type & WingHex::MetaTypeMask);
|
||||
switch (type) {
|
||||
case WingHex::Meta_Void:
|
||||
retype = QStringLiteral("void");
|
||||
break;
|
||||
case WingHex::Meta_Bool:
|
||||
retype = QStringLiteral("bool");
|
||||
break;
|
||||
case WingHex::Meta_Int:
|
||||
retype = QStringLiteral("int");
|
||||
break;
|
||||
case WingHex::Meta_UInt:
|
||||
retype = QStringLiteral("uint");
|
||||
break;
|
||||
case WingHex::Meta_Int8:
|
||||
retype = QStringLiteral("int8");
|
||||
break;
|
||||
case WingHex::Meta_UInt8:
|
||||
retype = QStringLiteral("uint8");
|
||||
break;
|
||||
case WingHex::Meta_Int16:
|
||||
retype = QStringLiteral("int16");
|
||||
break;
|
||||
case WingHex::Meta_UInt16:
|
||||
retype = QStringLiteral("uint16");
|
||||
break;
|
||||
case WingHex::Meta_Int64:
|
||||
retype = QStringLiteral("int64");
|
||||
break;
|
||||
case WingHex::Meta_UInt64:
|
||||
retype = QStringLiteral("uint64");
|
||||
break;
|
||||
case WingHex::Meta_Float:
|
||||
retype = QStringLiteral("float");
|
||||
break;
|
||||
case WingHex::Meta_Double:
|
||||
retype = QStringLiteral("double");
|
||||
break;
|
||||
case WingHex::Meta_String:
|
||||
retype = QStringLiteral("string");
|
||||
break;
|
||||
case WingHex::Meta_Char:
|
||||
retype = QStringLiteral("char");
|
||||
break;
|
||||
case WingHex::Meta_Byte:
|
||||
retype = QStringLiteral("byte");
|
||||
break;
|
||||
case WingHex::Meta_Color:
|
||||
retype = QStringLiteral("color");
|
||||
complexType = true;
|
||||
break;
|
||||
case WingHex::Meta_Map:
|
||||
case WingHex::Meta_Hash:
|
||||
retype = QStringLiteral("dictionary");
|
||||
complexType = true;
|
||||
break;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
if (isArray || isList) {
|
||||
retype.append(QStringLiteral("[]"));
|
||||
}
|
||||
|
||||
if (isArg) {
|
||||
if (!noModifier && (isContainer || complexType)) {
|
||||
retype.append(QStringLiteral(" &in"))
|
||||
.prepend(QStringLiteral("const "));
|
||||
}
|
||||
} else {
|
||||
if (!noModifier) {
|
||||
// if it's a return type, only array<byte> and array<string> are
|
||||
// supported in AngelScript
|
||||
// ( array<byte> -> QByteArray , array<string> -> QStringList ),
|
||||
// other array types are not suported. PRs are welcomed !!!
|
||||
// IT'S TOO COMPLEX TO SUPPORT QVARIANTLIST !!!
|
||||
|
||||
// You can use unsafe registering to support
|
||||
// extensive scripting system.
|
||||
// It will be faster and flexible but not easy to implement.
|
||||
if (isContainer) {
|
||||
if (type != WingHex::Meta_Byte &&
|
||||
type != WingHex::Meta_String) {
|
||||
return {};
|
||||
}
|
||||
|
||||
retype.append(QStringLiteral("@"));
|
||||
}
|
||||
|
||||
if (complexType) {
|
||||
retype.append(QStringLiteral("@"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retype.trimmed();
|
||||
}
|
||||
|
||||
void WingAngelAPI::script_call(asIScriptGeneric *gen) {
|
||||
auto fn = gen->GetFunction();
|
||||
|
||||
|
@ -1780,7 +1767,7 @@ void WingAngelAPI::script_call(asIScriptGeneric *gen) {
|
|||
}
|
||||
|
||||
auto rettype = fns.ret;
|
||||
auto r = PluginSystem::type2AngelScriptString(rettype, false, true);
|
||||
auto r = type2AngelScriptString(rettype, false, true);
|
||||
if (r == QStringLiteral("int")) {
|
||||
r = QStringLiteral("int32");
|
||||
} else if (r == QStringLiteral("uint")) {
|
||||
|
@ -1829,7 +1816,7 @@ void WingAngelAPI::script_unsafe_call(asIScriptGeneric *gen) {
|
|||
|
||||
QList<void *> params;
|
||||
auto total = gen->GetArgCount();
|
||||
WingHex::IWingPlugin::UNSAFE_RET ret;
|
||||
WingHex::UNSAFE_RET ret;
|
||||
for (decltype(total) i = 0; i < total; ++i) {
|
||||
auto raw = gen->GetAddressOfArg(i);
|
||||
params.append(raw);
|
||||
|
@ -1997,11 +1984,11 @@ WingAngelAPI::retriveAsDictionary(const WingHex::SenderInfo &sender,
|
|||
}
|
||||
|
||||
void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
|
||||
MetaType type,
|
||||
WingHex::MetaType type,
|
||||
const QVector<void *> &content) {
|
||||
Q_UNUSED(sender);
|
||||
auto typeStr = PluginSystem::type2AngelScriptString(
|
||||
MetaType(type | MetaType::Array), false, true);
|
||||
auto typeStr = type2AngelScriptString(
|
||||
WingHex::MetaType(type | WingHex::MetaType::Meta_Array), false, true);
|
||||
if (typeStr.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2018,14 +2005,15 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
|
|||
}
|
||||
|
||||
void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
|
||||
MetaType type, const QList<void *> &content) {
|
||||
WingHex::MetaType type,
|
||||
const QList<void *> &content) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
static_assert(std::is_same_v<QList<int>, QVector<int>>);
|
||||
return vector2AsArray(sender, type, content);
|
||||
#else
|
||||
Q_UNUSED(sender);
|
||||
auto typeStr = PluginSystem::type2AngelScriptString(
|
||||
MetaType(type | MetaType::Array), false, true);
|
||||
auto typeStr = type2AngelScriptString(MetaType(type | MetaType::Meta_Array),
|
||||
false, true);
|
||||
if (typeStr.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2054,7 +2042,7 @@ void WingAngelAPI::deleteAsArray(const WingHex::SenderInfo &sender,
|
|||
|
||||
void *WingAngelAPI::newAsDictionary(
|
||||
const WingHex::SenderInfo &sender,
|
||||
const QHash<QString, QPair<MetaType, void *>> &content) {
|
||||
const QHash<QString, QPair<WingHex::MetaType, void *>> &content) {
|
||||
Q_UNUSED(sender);
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
auto dic = CScriptDictionary::Create(engine);
|
||||
|
@ -2062,8 +2050,7 @@ void *WingAngelAPI::newAsDictionary(
|
|||
for (auto p = content.constKeyValueBegin(); p != content.constKeyValueEnd();
|
||||
++p) {
|
||||
auto key = p->first;
|
||||
auto typeStr =
|
||||
PluginSystem::type2AngelScriptString(p->second.first, false, true);
|
||||
auto typeStr = type2AngelScriptString(p->second.first, false, true);
|
||||
auto id = engine->GetTypeIdByDecl(typeStr.toUtf8());
|
||||
if (id < 0) {
|
||||
continue;
|
||||
|
|
|
@ -29,10 +29,22 @@ class asIScriptEngine;
|
|||
class ScriptMachine;
|
||||
class ScriptingConsole;
|
||||
|
||||
namespace WingScriptInternal {
|
||||
|
||||
struct ScriptFnInfo {
|
||||
uint ret; // MetaType
|
||||
QVector<QPair<uint, QString>> params;
|
||||
std::function<QVariant(const QVariantList &)> fn;
|
||||
};
|
||||
|
||||
} // namespace WingScriptInternal
|
||||
|
||||
class WingAngelAPI : public WingHex::IWingPlugin {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(WingHex::IWingPlugin)
|
||||
|
||||
friend class WingAngel;
|
||||
|
||||
public:
|
||||
WingAngelAPI();
|
||||
virtual ~WingAngelAPI();
|
||||
|
@ -48,25 +60,14 @@ public:
|
|||
|
||||
virtual QString retranslate(const QString &str) override;
|
||||
|
||||
virtual QStringList registerScriptMarcos() const override;
|
||||
|
||||
private:
|
||||
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
|
||||
|
||||
virtual void eventPluginFile(PluginFileEvent e, FileType type,
|
||||
const QString &newfileName, int handle,
|
||||
const QString &oldfileName) override;
|
||||
|
||||
public:
|
||||
void
|
||||
registerScriptFns(const QString &ns,
|
||||
const QHash<QString, IWingPlugin::ScriptFnInfo> &rfns);
|
||||
void registerUnSafeScriptFns(
|
||||
const QString &ns,
|
||||
const QHash<QString, IWingPlugin::UNSAFE_SCFNPTR> &rfns);
|
||||
|
||||
void
|
||||
registerScriptEnums(const QString &ns,
|
||||
const QHash<QString, QList<QPair<QString, int>>> &objs);
|
||||
|
||||
void installAPI(ScriptMachine *machine);
|
||||
void installBasicTypes(asIScriptEngine *engine);
|
||||
|
||||
|
@ -84,6 +85,10 @@ public:
|
|||
*reinterpret_cast<T *>(&buffer) = v;
|
||||
}
|
||||
|
||||
public:
|
||||
static QString type2AngelScriptString(uint type, bool isArg,
|
||||
bool noModifier);
|
||||
|
||||
private:
|
||||
void installLogAPI(asIScriptEngine *engine);
|
||||
void installExtAPI(asIScriptEngine *engine);
|
||||
|
@ -94,9 +99,6 @@ private:
|
|||
void installHexBaseType(asIScriptEngine *engine);
|
||||
void installHexReaderAPI(asIScriptEngine *engine);
|
||||
void installHexControllerAPI(asIScriptEngine *engine);
|
||||
void installScriptFns(asIScriptEngine *engine);
|
||||
void installScriptUnSafeFns(asIScriptEngine *engine);
|
||||
void installScriptEnums(asIScriptEngine *engine);
|
||||
|
||||
private:
|
||||
void registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn,
|
||||
|
@ -125,8 +127,7 @@ private:
|
|||
static QVariant qvariantGet(asIScriptEngine *engine, const void *raw,
|
||||
int typeID, bool flag);
|
||||
|
||||
static bool
|
||||
getQVariantGetFlag(const WingHex::IWingPlugin::ScriptFnInfo &info,
|
||||
static bool getQVariantGetFlag(const WingScriptInternal::ScriptFnInfo &info,
|
||||
int index);
|
||||
|
||||
template <typename T>
|
||||
|
@ -169,17 +170,17 @@ private:
|
|||
retriveAsDictionary(const WingHex::SenderInfo &sender, void *dic);
|
||||
|
||||
WING_SERVICE void *vector2AsArray(const WingHex::SenderInfo &sender,
|
||||
MetaType type,
|
||||
WingHex::MetaType type,
|
||||
const QVector<void *> &content);
|
||||
WING_SERVICE void *list2AsArray(const WingHex::SenderInfo &sender,
|
||||
MetaType type,
|
||||
WingHex::MetaType type,
|
||||
const QList<void *> &content);
|
||||
WING_SERVICE void deleteAsArray(const WingHex::SenderInfo &sender,
|
||||
void *array);
|
||||
|
||||
WING_SERVICE void *
|
||||
newAsDictionary(const WingHex::SenderInfo &sender,
|
||||
const QHash<QString, QPair<MetaType, void *>> &content);
|
||||
WING_SERVICE void *newAsDictionary(
|
||||
const WingHex::SenderInfo &sender,
|
||||
const QHash<QString, QPair<WingHex::MetaType, void *>> &content);
|
||||
WING_SERVICE void deleteAsDictionary(const WingHex::SenderInfo &sender,
|
||||
void *dic);
|
||||
|
||||
|
@ -284,13 +285,8 @@ private:
|
|||
QFileDialog::Options options);
|
||||
|
||||
private:
|
||||
QVector<IWingPlugin::ScriptFnInfo> _sfns;
|
||||
QHash<QString, QHash<QString, qsizetype>> _rfns;
|
||||
|
||||
QVector<IWingPlugin::UNSAFE_SCFNPTR> _usfns;
|
||||
QHash<QString, QHash<QString, qsizetype>> _urfns;
|
||||
|
||||
QHash<QString, QHash<QString, QList<QPair<QString, int>>>> _objs;
|
||||
QVector<WingScriptInternal::ScriptFnInfo> _sfns;
|
||||
QVector<WingHex::UNSAFE_SCFNPTR> _usfns;
|
||||
|
||||
QVector<int> _handles;
|
||||
};
|
||||
|
|
|
@ -17,164 +17,12 @@
|
|||
|
||||
#include "wingcstruct.h"
|
||||
|
||||
#include "WingPlugin/iwingangel.h"
|
||||
#include "scriptaddon/scriptqdictionary.h"
|
||||
#include "utilities.h"
|
||||
#include "wingangelapi.h"
|
||||
|
||||
WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::addStruct), this,
|
||||
std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
|
||||
info.params.append(
|
||||
qMakePair(MetaType::String, QStringLiteral("header")));
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("addStruct"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(QOverload<const QVariantList &>::of(
|
||||
&WingCStruct::addStructFromFile),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
|
||||
info.params.append(
|
||||
qMakePair(MetaType::String, QStringLiteral("fileName")));
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("addStructFromFile"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::resetEnv), this,
|
||||
std::placeholders::_1);
|
||||
info.ret = MetaType::Void;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("resetEnv"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::setStructPadding),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
|
||||
info.params.append(qMakePair(MetaType::Int, QStringLiteral("padding")));
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("setStructPadding"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::structPadding),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Int;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("structPadding"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::structPadding),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Int;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("structPadding"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::structTypes),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::String | MetaType::Array;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("structTypes"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::sizeofStruct),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = getqsizetypeMetaType();
|
||||
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
|
||||
_scriptInfo.insert(QStringLiteral("sizeofStruct"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::existStruct),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
|
||||
_scriptInfo.insert(QStringLiteral("existStruct"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::constDefines),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::String | MetaType::Array;
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("constDefines"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::existDefineValue),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Bool;
|
||||
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("existDefineValue"), info);
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::defineValue),
|
||||
this, std::placeholders::_1);
|
||||
info.ret = MetaType::Int;
|
||||
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("defineValue"), info);
|
||||
}
|
||||
|
||||
// nested dictionary is not supported, so unsafe registering will help
|
||||
{
|
||||
_scriptUnsafe.insert(
|
||||
QStringLiteral("dictionary@ read(") + getqsizeTypeAsString() +
|
||||
(" offset, const string &in type)"),
|
||||
std::bind(QOverload<const QList<void *> &>::of(&WingCStruct::read),
|
||||
this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
{
|
||||
WingHex::IWingPlugin::ScriptFnInfo info;
|
||||
info.fn = std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::readRaw), this,
|
||||
std::placeholders::_1);
|
||||
info.ret = MetaType::Byte | MetaType::Array;
|
||||
|
||||
info.params.append(
|
||||
qMakePair(getqsizetypeMetaType(), QStringLiteral("offset")));
|
||||
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
|
||||
|
||||
_scriptInfo.insert(QStringLiteral("readRaw"), info);
|
||||
}
|
||||
}
|
||||
WingCStruct::WingCStruct() : WingHex::IWingPlugin() {}
|
||||
|
||||
WingCStruct::~WingCStruct() {}
|
||||
|
||||
|
@ -203,7 +51,6 @@ QString WingCStruct::retranslate(const QString &str) {
|
|||
|
||||
WingCStruct::RegisteredEvents WingCStruct::registeredEvents() const {
|
||||
RegisteredEvents evs;
|
||||
evs.setFlag(RegisteredEvent::ScriptUnSafeFnRegistering);
|
||||
evs.setFlag(RegisteredEvent::ScriptPragma);
|
||||
evs.setFlag(RegisteredEvent::ScriptPragmaInit);
|
||||
return evs;
|
||||
|
@ -213,11 +60,6 @@ QList<WingHex::SettingPage *> WingCStruct::registeredSettingPages() const {
|
|||
return _setpgs;
|
||||
}
|
||||
|
||||
QHash<QString, WingCStruct::ScriptFnInfo>
|
||||
WingCStruct::registeredScriptFns() const {
|
||||
return _scriptInfo;
|
||||
}
|
||||
|
||||
bool WingCStruct::eventOnScriptPragma(const QString &script,
|
||||
const QStringList &comments) {
|
||||
// #pragma WingCStruct Arch [32 | 64]
|
||||
|
@ -288,9 +130,99 @@ bool WingCStruct::eventOnScriptPragma(const QString &script,
|
|||
|
||||
void WingCStruct::eventOnScriptPragmaInit() { resetEnv(); }
|
||||
|
||||
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR>
|
||||
WingCStruct::registeredScriptUnsafeFns() const {
|
||||
return _scriptUnsafe;
|
||||
void WingCStruct::onRegisterScriptObj(WingHex::IWingAngel *o) {
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Bool,
|
||||
std::bind(QOverload<const QVariantList &>::of(&WingCStruct::addStruct),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("addStruct"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("header"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Bool,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&WingCStruct::addStructFromFile),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("addStructFromFile"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("fileName"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Void,
|
||||
std::bind(QOverload<const QVariantList &>::of(&WingCStruct::resetEnv),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("resetEnv"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Bool,
|
||||
std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::setStructPadding),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("setStructPadding"),
|
||||
{qMakePair(WingHex::Meta_Int, QStringLiteral("padding"))});
|
||||
|
||||
o->registerGlobalFunction(WingHex::Meta_Int,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&WingCStruct::structPadding),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("structPadding"));
|
||||
|
||||
o->registerGlobalFunction(WingHex::Meta_String | WingHex::Meta_Array,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&WingCStruct::structTypes),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("structTypes"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
getqsizetypeMetaType(),
|
||||
std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::sizeofStruct),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("sizeofStruct"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Bool,
|
||||
std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::existStruct),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("existStruct"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
|
||||
|
||||
o->registerGlobalFunction(WingHex::Meta_String | WingHex::Meta_Array,
|
||||
std::bind(QOverload<const QVariantList &>::of(
|
||||
&WingCStruct::constDefines),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("constDefines"));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Bool,
|
||||
std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::existDefineValue),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("existDefineValue"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Int,
|
||||
std::bind(
|
||||
QOverload<const QVariantList &>::of(&WingCStruct::defineValue),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("defineValue"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
|
||||
|
||||
// nested dictionary is not supported, so unsafe registering will help
|
||||
o->registerGlobalFunction(
|
||||
QStringLiteral("dictionary@ read(") + getqsizeTypeAsString() +
|
||||
(" offset, const string &in type)"),
|
||||
std::bind(QOverload<const QList<void *> &>::of(&WingCStruct::read),
|
||||
this, std::placeholders::_1));
|
||||
|
||||
o->registerGlobalFunction(
|
||||
WingHex::Meta_Byte | WingHex::Meta_Array,
|
||||
std::bind(QOverload<const QVariantList &>::of(&WingCStruct::readRaw),
|
||||
this, std::placeholders::_1),
|
||||
QStringLiteral("readRaw"),
|
||||
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
|
||||
}
|
||||
|
||||
bool WingCStruct::addStruct(const QString &header) {
|
||||
|
@ -713,9 +645,9 @@ CScriptArray *WingCStruct::convert2AsArray(const QVariantList &array,
|
|||
return arr;
|
||||
}
|
||||
|
||||
WingHex::IWingPlugin::MetaType WingCStruct::getqsizetypeMetaType() const {
|
||||
return sizeof(qsizetype) == sizeof(quint64) ? MetaType::Int64
|
||||
: MetaType::Int32;
|
||||
WingHex::MetaType WingCStruct::getqsizetypeMetaType() const {
|
||||
return sizeof(qsizetype) == sizeof(quint64) ? WingHex::MetaType::Meta_Int64
|
||||
: WingHex::MetaType::Meta_Int32;
|
||||
}
|
||||
|
||||
QVariant WingCStruct::addStruct(const QVariantList ¶ms) {
|
||||
|
@ -834,8 +766,7 @@ QVariant WingCStruct::defineValue(const QVariantList ¶ms) {
|
|||
return defineValue(type);
|
||||
}
|
||||
|
||||
WingHex::IWingPlugin::UNSAFE_RET
|
||||
WingCStruct::read(const QList<void *> ¶ms) {
|
||||
WingHex::UNSAFE_RET WingCStruct::read(const QList<void *> ¶ms) {
|
||||
if (params.size() != 2) {
|
||||
return generateScriptCallError(-1, tr("InvalidParamsCount"));
|
||||
}
|
||||
|
|
|
@ -48,12 +48,13 @@ public:
|
|||
virtual RegisteredEvents registeredEvents() const override;
|
||||
virtual QList<WingHex::SettingPage *>
|
||||
registeredSettingPages() const override;
|
||||
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
|
||||
virtual bool eventOnScriptPragma(const QString &script,
|
||||
const QStringList &comments) override;
|
||||
virtual void eventOnScriptPragmaInit() override;
|
||||
virtual QHash<QString, UNSAFE_SCFNPTR>
|
||||
registeredScriptUnsafeFns() const override;
|
||||
|
||||
// IWingPluginCoreBase interface
|
||||
public:
|
||||
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
|
||||
|
||||
private:
|
||||
// basic
|
||||
|
@ -78,7 +79,7 @@ private:
|
|||
WING_SERVICE QByteArray readRaw(qsizetype offset, const QString &type);
|
||||
|
||||
private:
|
||||
MetaType getqsizetypeMetaType() const;
|
||||
WingHex::MetaType getqsizetypeMetaType() const;
|
||||
|
||||
QString getqsizeTypeAsString() const;
|
||||
|
||||
|
@ -111,15 +112,13 @@ private:
|
|||
QVariant existDefineValue(const QVariantList ¶ms);
|
||||
QVariant defineValue(const QVariantList ¶ms);
|
||||
|
||||
UNSAFE_RET read(const QList<void *> ¶ms);
|
||||
WingHex::UNSAFE_RET read(const QList<void *> ¶ms);
|
||||
QVariant readRaw(const QVariantList ¶ms);
|
||||
|
||||
private:
|
||||
CTypeParser _parser;
|
||||
|
||||
QList<WingHex::SettingPage *> _setpgs;
|
||||
QHash<QString, WingCStruct::ScriptFnInfo> _scriptInfo;
|
||||
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
|
||||
};
|
||||
|
||||
#endif // WINGCSTRUCT_H
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** 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 Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "winggeneric.h"
|
||||
|
||||
#include "angelscript.h"
|
||||
|
||||
WingGeneric::WingGeneric(asIScriptGeneric *gen) : _gen(gen) {}
|
||||
|
||||
int WingGeneric::argCount() const { return _gen->GetArgCount(); }
|
||||
|
||||
int WingGeneric::argTypeId(uint arg, quint32 *flags) const {
|
||||
static_assert(sizeof(quint32) == sizeof(asDWORD),
|
||||
"asDWORD is same with quint32");
|
||||
return _gen->GetArgTypeId(arg, reinterpret_cast<asDWORD *>(flags));
|
||||
}
|
||||
|
||||
QString WingGeneric::argTypeName(uint arg, quint32 *flags) {
|
||||
auto e = _gen->GetEngine();
|
||||
auto str = e->GetTypeDeclaration(argTypeId(arg, flags));
|
||||
if (str) {
|
||||
return str;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
uchar WingGeneric::argByte(uint arg) { return _gen->GetArgByte(arg); }
|
||||
|
||||
quint16 WingGeneric::argWord(uint arg) { return _gen->GetArgWord(arg); }
|
||||
|
||||
quint32 WingGeneric::argDWord(uint arg) { return _gen->GetArgDWord(arg); }
|
||||
|
||||
quint64 WingGeneric::argQWord(uint arg) { return _gen->GetArgQWord(arg); }
|
||||
|
||||
float WingGeneric::argFloat(uint arg) { return _gen->GetArgFloat(arg); }
|
||||
|
||||
double WingGeneric::argDouble(uint arg) { return _gen->GetArgDouble(arg); }
|
||||
|
||||
void *WingGeneric::argAddress(uint arg) { return _gen->GetArgAddress(arg); }
|
||||
|
||||
void *WingGeneric::argObject(uint arg) { return _gen->GetArgObject(arg); }
|
||||
|
||||
void *WingGeneric::addressOfArg(uint arg) { return _gen->GetAddressOfArg(arg); }
|
||||
|
||||
int WingGeneric::returnTypeId(quint32 *flags) const {
|
||||
static_assert(sizeof(quint32) == sizeof(asDWORD),
|
||||
"asDWORD is same with quint32");
|
||||
return _gen->GetReturnTypeId(reinterpret_cast<asDWORD *>(flags));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnByte(uchar val) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnByte(val));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnWord(quint16 val) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnWord(val));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnDWord(quint32 val) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnDWord(val));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnQWord(quint64 val) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnQWord(val));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnFloat(float val) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnFloat(val));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnDouble(double val) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnDouble(val));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnAddress(void *addr) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnAddress(addr));
|
||||
}
|
||||
|
||||
WingHex::asRetCodes WingGeneric::setReturnObject(void *obj) {
|
||||
return WingHex::asRetCodes(_gen->SetReturnObject(obj));
|
||||
}
|
||||
|
||||
void *WingGeneric::addressOfReturnLocation() {
|
||||
return _gen->GetAddressOfReturnLocation();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** 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 Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef WINGGENERIC_H
|
||||
#define WINGGENERIC_H
|
||||
|
||||
#include "WingPlugin/iwingangel.h"
|
||||
|
||||
class asIScriptGeneric;
|
||||
|
||||
class WingGeneric : public WingHex::IWingGeneric {
|
||||
public:
|
||||
explicit WingGeneric(asIScriptGeneric *gen);
|
||||
|
||||
// IWingGeneric interface
|
||||
public:
|
||||
int argCount() const override;
|
||||
int argTypeId(uint arg, quint32 *flags) const override;
|
||||
QString argTypeName(uint arg, quint32 *flags) override;
|
||||
uchar argByte(uint arg) override;
|
||||
quint16 argWord(uint arg) override;
|
||||
quint32 argDWord(uint arg) override;
|
||||
quint64 argQWord(uint arg) override;
|
||||
float argFloat(uint arg) override;
|
||||
double argDouble(uint arg) override;
|
||||
void *argAddress(uint arg) override;
|
||||
void *argObject(uint arg) override;
|
||||
void *addressOfArg(uint arg) override;
|
||||
int returnTypeId(quint32 *flags) const override;
|
||||
WingHex::asRetCodes setReturnByte(uchar val) override;
|
||||
WingHex::asRetCodes setReturnWord(quint16 val) override;
|
||||
WingHex::asRetCodes setReturnDWord(quint32 val) override;
|
||||
WingHex::asRetCodes setReturnQWord(quint64 val) override;
|
||||
WingHex::asRetCodes setReturnFloat(float val) override;
|
||||
WingHex::asRetCodes setReturnDouble(double val) override;
|
||||
WingHex::asRetCodes setReturnAddress(void *addr) override;
|
||||
WingHex::asRetCodes setReturnObject(void *obj) override;
|
||||
void *addressOfReturnLocation() override;
|
||||
|
||||
private:
|
||||
asIScriptGeneric *_gen;
|
||||
};
|
||||
|
||||
#endif // WINGGENERIC_H
|
|
@ -234,11 +234,28 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
|
|||
auto &sm = ScriptMachine::instance();
|
||||
auto smr = sm.init();
|
||||
if (smr) {
|
||||
plg.doneRegisterScriptObj();
|
||||
auto cfgerr = sm.isEngineConfigError();
|
||||
|
||||
// At this time, AngelScript service plugin has started
|
||||
if (cfgerr) {
|
||||
m_scriptConsole->initOutput();
|
||||
m_scriptConsole->setMode(QConsoleWidget::Output);
|
||||
m_scriptConsole->stdErr(tr("EngineConfigError"));
|
||||
|
||||
m_scriptConsole->setEnabled(false);
|
||||
|
||||
// configure error, so disable all script feature
|
||||
WingHex::WingRibbonToolBoxInfo::RibbonCatagories catagories;
|
||||
m_ribbonMaps[catagories.SCRIPT]->setEnabled(false);
|
||||
} else {
|
||||
ScriptMachine::RegCallBacks callbacks;
|
||||
callbacks.getInputFn = [this]() -> QString {
|
||||
return m_scriptConsole->getInput();
|
||||
};
|
||||
callbacks.clearFn = [this]() { m_scriptConsole->clearConsole(); };
|
||||
callbacks.clearFn = [this]() {
|
||||
m_scriptConsole->clearConsole();
|
||||
};
|
||||
callbacks.printMsgFn =
|
||||
[this](const ScriptMachine::MessageInfo &message) {
|
||||
m_scriptConsole->onOutput(message);
|
||||
|
@ -254,15 +271,7 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
|
|||
std::bind(&MainWindow::onOutputBgScriptOutput, this,
|
||||
std::placeholders::_1);
|
||||
sm.registerCallBack(ScriptMachine::Background, callbacks);
|
||||
} else {
|
||||
QMessageBox::critical(this, qAppName(),
|
||||
tr("ScriptEngineInitFailed"));
|
||||
set.setScriptEnabled(false);
|
||||
set.save(SettingManager::SCRIPT);
|
||||
throw CrashCode::ScriptInitFailed;
|
||||
}
|
||||
|
||||
// At this time, AngelScript service plugin has started
|
||||
if (splash)
|
||||
splash->setInfoText(tr("SetupConsole"));
|
||||
|
||||
|
@ -281,6 +290,14 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
|
|||
m_scriptDialog = new ScriptingDialog(this);
|
||||
m_scriptDialog->initConsole();
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(this, qAppName(),
|
||||
tr("ScriptEngineInitFailed"));
|
||||
set.setScriptEnabled(false);
|
||||
set.save(SettingManager::SCRIPT);
|
||||
throw CrashCode::ScriptInitFailed;
|
||||
}
|
||||
}
|
||||
|
||||
// connect settings signals
|
||||
connect(&set, &SettingManager::sigEditorfontSizeChanged, this,
|
||||
|
|
|
@ -313,6 +313,23 @@ public:
|
|||
return dec->toUnicode(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool isValidIdentifier(const QString &str) {
|
||||
if (str.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
auto pch = str.cbegin();
|
||||
if (pch->isDigit()) {
|
||||
return false;
|
||||
}
|
||||
pch++;
|
||||
for (; pch != str.cend(); pch++) {
|
||||
if (!pch->isLetterOrNumber() && *pch != '_') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // UTILITIES_H
|
||||
|
|
Loading…
Reference in New Issue