1 /*
2 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <string>
17 #include "aki/jsbind.h"
18 #include <aki/version.h>
19 #include "napi/native_api.h"
20
21 // Function
SayHello(std::string msg)22 std::string SayHello(std::string msg)
23 {
24 return msg + " too.";
25 }
26
AsyncSayHello(std::string msg)27 std::string AsyncSayHello(std::string msg)
28 {
29 // Do something;
30 return msg + " too.";
31 }
32
33 // Class
34 class TestObject {
35 public:
TestObject()36 TestObject()
37 {
38 value_ = -1;
39 result = -1;
40 };
41
TestObject(double test)42 explicit TestObject(double test)
43 {
44 value_ = test;
45 }
46
47 ~TestObject() = default;
48
MultiplyObject(TestObject obj1, TestObject obj2)49 static double MultiplyObject(TestObject obj1, TestObject obj2)
50 {
51 return obj1.value_ * obj2.value_;
52 }
53
Multiply(double mult)54 double Multiply(double mult)
55 {
56 value_ *= mult;
57 return value_;
58 }
59
GetValue() const60 double GetValue() const
61 {
62 return value_;
63 }
64
SetValue(double value)65 void SetValue(double value)
66 {
67 value_ = value;
68 }
69 double result;
70 private:
71 double value_;
72 }; // TestObject
73
JSBIND_CLASS(TestObject)74 JSBIND_CLASS(TestObject)
75 {
76 JSBIND_CONSTRUCTOR<>();
77 JSBIND_CONSTRUCTOR<double>();
78 JSBIND_METHOD(MultiplyObject);
79 JSBIND_METHOD(Multiply);
80 JSBIND_FIELD("value", GetValue, SetValue);
81 JSBIND_PROPERTY(result);
82 }
83
84 // Enum
85 enum TypeFlags {
86 NONE,
87 NUM,
88 STRING,
89 BUTT = -1
90 };
91
JSBIND_ENUM(TypeFlags)92 JSBIND_ENUM(TypeFlags) {
93 JSBIND_ENUM_VALUE(NONE);
94 JSBIND_ENUM_VALUE(NUM);
95 JSBIND_ENUM_VALUE(STRING);
96 }
97
Passing(TypeFlags flag)98 TypeFlags Passing(TypeFlags flag)
99 {
100 return flag;
101 }
102
103 // PostTask
104
ReturnPromiseResolveLater()105 static aki::Promise ReturnPromiseResolveLater()
106 {
107 aki::Promise promise;
108
109 std::thread t([promise] () {
110 aki::TaskRunner::PostTask("main", [promise] () {
111 promise.Resolve(1);
112 });
113 });
114 t.detach();
115 return promise;
116 }
117
118 // arraybuffer
AsyncTaskReturnArrayBufferWithCommit(aki::ArrayBuffer input)119 aki::ArrayBuffer AsyncTaskReturnArrayBufferWithCommit(aki::ArrayBuffer input)
120 {
121 uint8_t temp[4] = {10, 20, 30, 40};
122 aki::ArrayBuffer arrayBufferOne(temp, TypeFlags.NUM);
123 aki::ArrayBuffer arrayBufferTwo(input.GetData(), input.GetLength());
124 arrayBufferOne.Commit();
125 return arrayBufferOne;
126 }
127
128 // aki-value
GetFromGlobal(aki::Value obj)129 std::string GetFromGlobal(aki::Value obj)
130 {
131 aki::Value jsonObj = aki::Value::FromGlobal("JSON");
132 aki::Value strObj = jsonObj["stringify"](obj);
133 return strObj.As<std::string>();
134 }
135
ConvertToString(aki::Value obj)136 std::string ConvertToString(aki::Value obj)
137 {
138 if (obj.IsNull()) {
139 return "null value";
140 } else if (obj.IsArray()) {
141 obj.CallMethod("push", "from C++");
142 aki::Value val1 = obj[0];
143 aki::Value strObj = aki::Value::FromGlobal("JSON")["stringify"](obj);
144 return strObj.As<std::string>();
145 } else if (obj.IsBool()) {
146 return obj.As<std::string>();
147 } else if (obj.IsNumber()) {
148 return obj.As<std::string>();
149 } else if (obj.IsString()) {
150 aki::Value val = aki::Value::NewObject();
151 val.Set("name", obj.As<std::string>());
152 aki::Value strObj = aki::Value::FromGlobal("JSON")["stringify"](val);
153 return strObj.As<std::string>();
154 } else {
155 napi_value nvalue = obj.GetHandle();
156 napi_value nage, nname;
157 napi_get_named_property(aki::JSBind::GetScopedEnv(), nvalue, "age", &nage);
158 napi_get_named_property(aki::JSBind::GetScopedEnv(), nvalue, "name", &nname);
159
160 int age;
161 std::string name;
162 napi_get_value_int32(aki::JSBind::GetScopedEnv(), nage, &age);
163
164 size_t stringSize = 0;
165 napi_get_value_string_utf8(aki::JSBind::GetScopedEnv(), nname, nullptr, 0, &stringSize); // 获取字符串长度
166 name.resize(stringSize + 1);
167
168 // 根据长度传换成字符串
169 napi_get_value_string_utf8(aki::JSBind::GetScopedEnv(), nname, &name[0], stringSize + 1, &stringSize);
170 AKI_LOG(INFO) << name << " : " << age;
171 }
172 }
173
174
175 // Step 1 注册 AKI 插件
176 JSBIND_ADDON(hello) // 注册 AKI 插件名: 即为编译*.so名称,规则与NAPI一致
177
178 // Step 2 注册 FFI 特性
JSBIND_GLOBAL()179 JSBIND_GLOBAL() {
180 JSBIND_FUNCTION(SayHello);
181 JSBIND_PFUNCTION(AsyncSayHello);
182 JSBIND_FUNCTION(Passing);
183 JSBIND_FUNCTION(ReturnPromiseResolveLater);
184 JSBIND_PFUNCTION(AsyncTaskReturnArrayBufferWithCommit);
185 JSBIND_FUNCTION(ConvertToString);
186 }