#include "APIHelp.h" #include "GuiAPI.h" #include "PlayerAPI.h" #include "McAPI.h" #include #include #include #include #include #include using namespace std; using namespace Form; //////////////////// Class Definition //////////////////// ClassDefine SimpleFormClassBuilder = defineClass("LLSE_SimpleForm") .constructor(nullptr) .instanceFunction("setTitle", &SimpleFormClass::setTitle) .instanceFunction("setContent", &SimpleFormClass::setContent) .instanceFunction("addButton", &SimpleFormClass::addButton) .build(); ClassDefine CustomFormClassBuilder = defineClass("LLSE_CustomForm") .constructor(nullptr) .instanceFunction("setTitle", &CustomFormClass::setTitle) .instanceFunction("addLabel", &CustomFormClass::addLabel) .instanceFunction("addInput", &CustomFormClass::addInput) .instanceFunction("addSwitch", &CustomFormClass::addSwitch) .instanceFunction("addDropdown", &CustomFormClass::addDropdown) .instanceFunction("addSlider", &CustomFormClass::addSlider) .instanceFunction("addStepSlider", &CustomFormClass::addStepSlider) .build(); //////////////////// Simple Form //////////////////// SimpleFormClass::SimpleFormClass() : ScriptClass(ScriptClass::ConstructFromCpp{}), form("", "") { } //生成函数 Local SimpleFormClass::newForm() { auto newp = new SimpleFormClass(); return newp->getScriptObject(); } Form::SimpleForm* SimpleFormClass::extract(Local v) { if (EngineScope::currentEngine()->isInstanceOf(v)) return EngineScope::currentEngine()->getNativeInstance(v)->get(); else return nullptr; } bool SimpleFormClass::sendForm(Form::SimpleForm* form, Player* player, script::Local& callback) { script::Global callbackFunc{callback}; return form->sendTo(player, [engine{EngineScope::currentEngine()}, callback{std::move(callbackFunc)}](Player* pl, int chosen) { if (LL::isServerStopping()) return; if (!EngineManager::isValid(engine)) return; if (callback.isEmpty()) return; EngineScope scope(engine); try { if (chosen < 0) callback.get().call({}, PlayerClass::newPlayer(pl), Local()); else callback.get().call({}, PlayerClass::newPlayer(pl), Number::newNumber(chosen)); } CATCH_WITHOUT_RETURN("Fail in form callback!") }); } //成员函数 Local SimpleFormClass::setTitle(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); CHECK_ARG_TYPE(args[0], ValueKind::kString); try { form.title = args[0].toStr(); return this->getScriptObject(); } CATCH("Fail in setTitle!") } Local SimpleFormClass::setContent(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); CHECK_ARG_TYPE(args[0], ValueKind::kString); try { form.content = args[0].toStr(); return this->getScriptObject(); } CATCH("Fail in setTitle!") } Local SimpleFormClass::addButton(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); CHECK_ARG_TYPE(args[0], ValueKind::kString); if (args.size() >= 2) CHECK_ARG_TYPE(args[1], ValueKind::kString); try { string image = args.size() >= 2 ? args[1].toStr() : ""; form.append(Button(args[0].toStr(), image)); return this->getScriptObject(); } CATCH("Fail in addButton!") } //////////////////// Custom Form //////////////////// CustomFormClass::CustomFormClass() : ScriptClass(ScriptClass::ConstructFromCpp{}), form("") { } //生成函数 Local CustomFormClass::newForm() { auto newp = new CustomFormClass(); return newp->getScriptObject(); } CustomForm* CustomFormClass::extract(Local v) { if (EngineScope::currentEngine()->isInstanceOf(v)) return EngineScope::currentEngine()->getNativeInstance(v)->get(); else return nullptr; } //成员函数 bool CustomFormClass::sendForm(Form::CustomForm* form, Player* player, script::Local& callback) { script::Global callbackFunc{callback}; return form->sendToForRawJson(player, [engine{EngineScope::currentEngine()}, callback{std::move(callbackFunc)}](Player* pl, string data) { if (LL::isServerStopping()) return; if (!EngineManager::isValid(engine)) return; if (callback.isEmpty()) return; EngineScope scope(engine); try { callback.get().call({}, PlayerClass::newPlayer(pl), JsonToValue(data)); } CATCH_WITHOUT_RETURN("Fail in form callback!") }); } Local CustomFormClass::setTitle(const Arguments& args) { CHECK_ARGS_COUNT(args, 1) CHECK_ARG_TYPE(args[0], ValueKind::kString) try { form.title = args[0].toStr(); return this->getScriptObject(); } CATCH("Fail in setTitle!") } Local CustomFormClass::addLabel(const Arguments& args) { CHECK_ARGS_COUNT(args, 1) CHECK_ARG_TYPE(args[0], ValueKind::kString) try { form.append(Label(args[0].toStr(), args[0].toStr())); return this->getScriptObject(); } CATCH("Fail in addLabel!") } Local CustomFormClass::addInput(const Arguments& args) { CHECK_ARGS_COUNT(args, 1) CHECK_ARG_TYPE(args[0], ValueKind::kString) if (args.size() >= 2) CHECK_ARG_TYPE(args[1], ValueKind::kString); if (args.size() >= 3) CHECK_ARG_TYPE(args[2], ValueKind::kString); try { string placeholder = args.size() >= 2 ? args[1].toStr() : ""; string def = args.size() >= 3 ? args[2].toStr() : ""; form.append(Input(args[0].toStr(), args[0].toStr(), placeholder, def)); return this->getScriptObject(); } CATCH("Fail in addInput!") } Local CustomFormClass::addSwitch(const Arguments& args) { CHECK_ARGS_COUNT(args, 1) CHECK_ARG_TYPE(args[0], ValueKind::kString) if (args.size() >= 2) CHECK_ARG_TYPE(args[1], ValueKind::kBoolean); try { bool def = args.size() >= 2 ? args[1].asBoolean().value() : false; form.append(Toggle(args[0].toStr(), args[0].toStr(), def)); return this->getScriptObject(); } CATCH("Fail in addSwitch!") } Local CustomFormClass::addDropdown(const Arguments& args) { CHECK_ARGS_COUNT(args, 2) CHECK_ARG_TYPE(args[0], ValueKind::kString) CHECK_ARG_TYPE(args[1], ValueKind::kArray); if (args.size() >= 3) CHECK_ARG_TYPE(args[2], ValueKind::kNumber); try { auto optionsArr = args[1].asArray(); vector options; for (int i = 0; i < optionsArr.size(); ++i) options.push_back(optionsArr.get(i).toStr()); int def = args.size() >= 3 ? args[2].asNumber().toInt32() : 0; form.append(Dropdown(args[0].toStr(), args[0].toStr(), options, def)); return this->getScriptObject(); } CATCH("Fail in addDropdown!") } Local CustomFormClass::addSlider(const Arguments& args) { CHECK_ARGS_COUNT(args, 3) CHECK_ARG_TYPE(args[0], ValueKind::kString) CHECK_ARG_TYPE(args[1], ValueKind::kNumber); CHECK_ARG_TYPE(args[2], ValueKind::kNumber); if (args.size() >= 4) CHECK_ARG_TYPE(args[3], ValueKind::kNumber); if (args.size() >= 5) CHECK_ARG_TYPE(args[4], ValueKind::kNumber); try { int minValue = args[1].asNumber().toInt32(); int maxValue = args[2].asNumber().toInt32(); if (minValue >= maxValue) maxValue = minValue + 1; int step = args.size() >= 4 ? args[3].asNumber().toInt32() : 1; int defValue = args.size() >= 5 ? args[4].asNumber().toInt32() : minValue; if (defValue < minValue || defValue > maxValue) defValue = minValue; form.append(Slider(args[0].toStr(), args[0].toStr(), minValue, maxValue, step, defValue)); return this->getScriptObject(); } CATCH("Fail in addSlider!") } Local CustomFormClass::addStepSlider(const Arguments& args) { CHECK_ARGS_COUNT(args, 2) CHECK_ARG_TYPE(args[0], ValueKind::kString) CHECK_ARG_TYPE(args[1], ValueKind::kArray); if (args.size() >= 3) CHECK_ARG_TYPE(args[2], ValueKind::kNumber); try { auto stepsArr = args[1].asArray(); vector steps; for (int i = 0; i < stepsArr.size(); ++i) steps.push_back(stepsArr.get(i).toStr()); int defIndex = args.size() >= 3 ? args[2].asNumber().toInt32() : 0; form.append(StepSlider(args[0].toStr(), args[0].toStr(), steps, defIndex)); return this->getScriptObject(); } CATCH("Fail in addStepSlider!") } //////////////////// APIs //////////////////// Local McClass::newSimpleForm(const Arguments& args) { return SimpleFormClass::newForm(); } Local McClass::newCustomForm(const Arguments& args) { return CustomFormClass::newForm(); }