Skip to content

Commit 2bb9f89

Browse files
committed
feat: add engine api
1 parent 4a71c68 commit 2bb9f89

File tree

5 files changed

+146
-58
lines changed

5 files changed

+146
-58
lines changed

src/Entry.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ void Entry::onLoad() {
2424
#if (defined(WIN32) || defined(_WIN32)) && defined(DEBUG)
2525
getLogger().setLevel(endstone::Logger::Debug);
2626
getLogger().info("Waiting for VC debugger attach...");
27-
while (!IsDebuggerPresent()) {
28-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
29-
}
27+
// while (!IsDebuggerPresent()) {
28+
// std::this_thread::sleep_for(std::chrono::milliseconds(100));
29+
// }
3030
#endif
3131
NodeManager::getInstance().initNodeJs();
3232
getLogger().info("Load javascript plugin...");

src/manager/RegisterGlobalFunc.h

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,100 @@
11
#pragma once
22
#include "DeclarationGenerator.h"
33
#include "JSClassRegister.h"
4+
#include "ScriptBackend.hpp"
5+
#include "V8Backend.hpp"
6+
#include "endstone/command/command_executor.h"
7+
#include "endstone/plugin/plugin.h"
8+
#include "manager/NodeManager.h"
49
#include "manager/V8Engine.h"
510
#include "v8-context.h"
11+
#include "v8-exception.h"
612
#include "v8-external.h"
713
#include "v8-function-callback.h"
14+
#include "v8-isolate.h"
815
#include "v8-local-handle.h"
16+
#include "v8-locker.h"
917
#include "v8-primitive.h"
1018
#include "v8-template.h"
1119
#include "v8-value.h"
20+
#include "v8_utils/V8Exception.h"
21+
#include "v8_utils/V8Util.h"
22+
#include <iostream>
1223
#include <string>
1324

25+
26+
UsingCppType(endstone::Plugin);
27+
UsingCppType(endstone::CommandExecutor);
28+
29+
struct AutoBinding {
30+
AutoBinding() {
31+
puerts::DefineClass<endstone::CommandExecutor>().Register();
32+
33+
puerts::DefineClass<endstone::Plugin>()
34+
.Extends<endstone::CommandExecutor>()
35+
// .Method("getDescription", &endstone::Plugin::getDescription)
36+
.Method("onLoad", MakeFunction(&endstone::Plugin::onLoad))
37+
.Method("onEnable", MakeFunction(&endstone::Plugin::onEnable))
38+
.Method("onDisable", MakeFunction(&endstone::Plugin::onDisable))
39+
.Method("getName", MakeFunction(&endstone::Plugin::getName))
40+
.Register();
41+
}
42+
};
43+
AutoBinding __AutoBinding__;
44+
45+
1446
namespace jse {
1547

48+
49+
inline void Js_RegisterPlugin(const v8::FunctionCallbackInfo<v8::Value>& args) {}
50+
51+
inline void Js_GetPlugin(const v8::FunctionCallbackInfo<v8::Value>& args) {
52+
auto isolate = v8::Isolate::GetCurrent();
53+
54+
v8::Isolate::Scope isolate_scope(isolate);
55+
v8::HandleScope handle_scope(isolate);
56+
57+
auto ctx = isolate->GetCurrentContext();
58+
59+
v8::Context::Scope context_scope(ctx);
60+
v8::TryCatch vtry{isolate};
61+
62+
auto _IdVal = ctx->Global()->Get(ctx, v8::String::NewFromUtf8Literal(isolate, "__ENGINE_ID__")).ToLocalChecked();
63+
auto _DoubleId = _IdVal->ToNumber(ctx).ToLocalChecked()->Value();
64+
auto id = static_cast<EngineID>(_DoubleId);
65+
66+
std::cout << "GetEngine id: " << id << std::endl;
67+
68+
auto engine = NodeManager::getInstance().getEngine(id);
69+
v8_exception::checkTryCatch(vtry);
70+
}
71+
72+
inline void RegisterEngineApi() {
73+
auto isolate = v8::Isolate::GetCurrent();
74+
75+
v8::Locker locker(isolate);
76+
v8::Isolate::Scope isolate_scope(isolate);
77+
v8::HandleScope handle_scope(isolate);
78+
79+
auto ctx = v8::Context::New(isolate);
80+
v8::Context::Scope context_scope(ctx);
81+
82+
// Engine.registerPlugin()
83+
// Engine.getSelf()
84+
auto tpl = v8::ObjectTemplate::New(isolate);
85+
tpl->Set(
86+
v8::String::NewFromUtf8Literal(isolate, "registerPlugin"),
87+
v8::FunctionTemplate::New(isolate, Js_RegisterPlugin)
88+
);
89+
90+
tpl->Set(v8::String::NewFromUtf8Literal(isolate, "getSelf"), v8::FunctionTemplate::New(isolate, Js_GetPlugin));
91+
92+
tpl->NewInstance(ctx).ToLocalChecked();
93+
ctx->Global()
94+
->Set(ctx, v8::String::NewFromUtf8Literal(isolate, "Engine"), tpl->NewInstance(ctx).ToLocalChecked())
95+
.Check();
96+
}
97+
1698
inline void RegisterGlobalFunc(V8Engine* wrapper) {
1799
auto isolate = wrapper->isolate();
18100
auto ctx = wrapper->context();
@@ -62,13 +144,13 @@ inline void RegisterGlobalFunc(V8Engine* wrapper) {
62144
)
63145
.Check();
64146

65-
global
66-
->Set(
67-
ctx,
68-
v8::String::NewFromUtf8(isolate, "__ENGINE_ID__").ToLocalChecked(),
69-
v8::Number::New(isolate, static_cast<double>(wrapper->mID))
70-
)
71-
.Check();
147+
v8_util::DefineReadOnlyGlobal(
148+
isolate,
149+
"__ENGINE_ID__",
150+
v8::Number::New(isolate, static_cast<double>(wrapper->mID))
151+
);
152+
153+
RegisterEngineApi();
72154
}
73155

74156

src/v8_utils/V8Util.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
#include "v8-context.h"
3+
#include "v8-exception.h"
4+
#include "v8-external.h"
5+
#include "v8-local-handle.h"
6+
#include "v8-value.h"
7+
8+
namespace v8_util {
9+
10+
// 定义只读的全局变量
11+
inline void DefineReadOnlyGlobal(v8::Isolate* isolate, const char* name, v8::Local<v8::Value> value) {
12+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
13+
v8::Local<v8::Object> global = context->Global();
14+
15+
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, name).ToLocalChecked();
16+
17+
auto attrs =
18+
static_cast<v8::PropertyAttribute>(v8::PropertyAttribute::ReadOnly | v8::PropertyAttribute::DontDelete);
19+
20+
global->DefineOwnProperty(context, key, value, attrs).Check();
21+
}
22+
23+
// 获取全局变量
24+
[[nodiscard]] inline v8::Local<v8::Value> GetGlobalVariable(v8::Isolate* isolate, const char* name) {
25+
v8::EscapableHandleScope handle_scope(isolate);
26+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
27+
v8::Local<v8::Object> global = context->Global();
28+
29+
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, name).ToLocalChecked();
30+
31+
return handle_scope.Escape(global->Get(context, key).ToLocalChecked());
32+
}
33+
34+
35+
} // namespace v8_util

test/test_js_plugin.js

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"use strict"
12
console.log("__ENGINE_ID__: ", __ENGINE_ID__);
23
console.log("__declaration__: ", __declaration__);
34
console.log("loadNativeClass: ", loadNativeClass);
@@ -12,41 +13,17 @@ function GenerateDTS() {
1213
GenerateDTS();
1314

1415
// 测试注册
15-
const JSE = loadNativeClass("JSEAPI");
16-
console.log("JSE", JSE);
17-
console.log("JSE.registerPlugin:", JSE.registerPlugin);
18-
console.log("JSE.isWindows:", JSE.isWindows, JSE.isWindows());
19-
console.log("JSE.isLinux:", JSE.isLinux, JSE.isLinux());
20-
21-
function ref(x) {
22-
return [x];
23-
}
24-
25-
const TestBuilder = loadNativeClass("TestBuilder");
26-
const obj = new TestBuilder();
27-
obj.name = "test";
28-
obj.version = "1.0.0";
29-
obj.description = "test";
30-
obj.onLoad = function () {
16+
function onLoad() {
3117
console.log("onLoad");
32-
};
33-
obj.onEnable = function () {
18+
}
19+
function onEnable() {
3420
console.log("onEnable");
35-
};
36-
obj.onDisable = function () {
21+
}
22+
function onDisable() {
3723
console.log("onDisable");
38-
};
24+
}
3925

40-
JSE.registerPlugin(obj); // TODO: Fix this,此方法不知道为什么会引发异常:Error: access a null object
41-
// [JsEngine] Uncaught v8_exception: Error: access a null object
42-
// [JsEngine] Error: access a null object
43-
// [JsEngine] at Object.<anonymous> (D:\Codes\Js_Engine\test\test_js_plugin.js:40:5)
44-
// [JsEngine] at Module._compile (node:internal/modules/cjs/loader:1565:14)
45-
// [JsEngine] at Module._extensions..js (node:internal/modules/cjs/loader:1708:10)
46-
// [JsEngine] at Module.load (node:internal/modules/cjs/loader:1318:32)
47-
// [JsEngine] at Module._load (node:internal/modules/cjs/loader:1128:12)
48-
// [JsEngine] at TracingChannel.traceSync (node:diagnostics_channel:322:14)
49-
// [JsEngine] at wrapModuleLoad (node:internal/modules/cjs/loader:219:24)
50-
// [JsEngine] at Module.require (node:internal/modules/cjs/loader:1340:12)
51-
// [JsEngine] at require (node:internal/modules/helpers:138:16)
52-
// [JsEngine] at D:\Codes\bedrock_server\bedrock_server.exe:21:21
26+
__ENGINE_ID__++;
27+
__ENGINE_ID__ = 10;
28+
29+
console.log("__ENGINE_ID__: ", __ENGINE_ID__);

types/AutoGen.d.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
1-
declare module "JSEAPI" {
1+
declare module "endstone::CommandExecutor" {
22
import {$Ref, $Nullable, cstring} from "puerts"
33

4-
class JSEAPI {
5-
static registerPlugin(p0: TestBuilder) :boolean;
6-
static isWindows() :boolean;
7-
static isLinux() :boolean;
4+
class endstone::CommandExecutor {
85
}
96

107
}
11-
declare module "TestBuilder" {
8+
declare module "endstone::Plugin" {
129
import {$Ref, $Nullable, cstring} from "puerts"
1310

14-
class TestBuilder {
15-
constructor();
16-
name: string;
17-
version: string;
18-
description: string;
19-
onLoad: () => void;
20-
onEnable: () => void;
21-
onDisable: () => void;
11+
class endstone::Plugin extends endstone::CommandExecutor {
12+
onLoad() :void;
13+
onEnable() :void;
14+
onDisable() :void;
15+
getName() :string;
2216
}
2317

2418
}

0 commit comments

Comments
 (0)