summaryrefslogtreecommitdiff
path: root/Taler/NodeWrapper.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Taler/NodeWrapper.swift')
-rw-r--r--Taler/NodeWrapper.swift106
1 files changed, 84 insertions, 22 deletions
diff --git a/Taler/NodeWrapper.swift b/Taler/NodeWrapper.swift
index 60ca92b..ec0ba58 100644
--- a/Taler/NodeWrapper.swift
+++ b/Taler/NodeWrapper.swift
@@ -1,49 +1,111 @@
-//
-// NodeWrapper.swift
-// Taler
-//
-// Created by Jonathan Buchanan on 1/14/21.
-// Copyright © 2021 Taler. All rights reserved.
-//
+/*
+ * This file is part of GNU Taler
+ * (C) 2021 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
import Foundation
+protocol IonoMessageHandler {
+ func handleMessage(message: String)
+}
+
+func notification_callback(payload: Optional<UnsafePointer<Int8>>,
+ userdata: Optional<UnsafeMutableRawPointer>) {
+ let native = Unmanaged<Iono>.fromOpaque(userdata!).takeUnretainedValue()
+ let string = String(cString: payload!)
+ native.internalOnNotify(payload: string)
+}
+
class Iono {
- var __instance: OpaquePointer
- var messageHandler: ((String) -> ())?
+ var instance: OpaquePointer!
+ var work_queue: DispatchQueue
+ var initialization_group: DispatchGroup
+ var messageHandler: IonoMessageHandler?
init() {
- __instance = __new_instance()
+ work_queue = DispatchQueue(label: "NodeQueue", qos: .userInitiated)
+ initialization_group = DispatchGroup()
+ initialization_group.notify(queue: work_queue) {
+ self.instance = __initNative()
+ __setNotifyHandler(self.instance, notification_callback, Unmanaged.passUnretained(self).toOpaque())
+ }
}
deinit {
- __free_instance(__instance)
+ __destroyNative(instance)
+ }
+
+ private func scheduleNodeThreadAsync(block: @escaping () -> Void) {
+ initialization_group.wait()
+ work_queue.async(execute: block)
+ notifyNative()
+ }
+
+ private func scheduleNodeThreadSync(block: @escaping () -> Void) {
+ initialization_group.wait()
+ work_queue.sync(execute: block)
+ notifyNative()
+ }
+
+ func internalOnNotify(payload: String) {
+ if let handler = messageHandler {
+ handler.handleMessage(message: payload)
+ }
}
func notifyNative() {
-
+ initialization_group.wait()
+ __notifyNative(instance)
}
- func evalJS(source: String) -> String {
- var result_cstr: UnsafeMutablePointer<Int8> = __eval_js(source.cString(using: .utf8), __instance)
- var result = String(cString: result_cstr)
- free(result_cstr)
- return result
+ func evalSimpleJs(source: String) -> String {
+ var result: String?
+ scheduleNodeThreadSync {
+ let cResult = __evalJs(self.instance, source.cString(using: .utf8))
+ if let cStr = cResult {
+ result = String(cString: cStr)
+ free(cResult)
+ }
+ }
+ return result!
}
func evalNodeCode(source: String) {
- __make_callback(source.cString(using: .utf8), __instance)
+ scheduleNodeThreadAsync {
+ __makeCallbackNative(self.instance, source.cString(using: .utf8))
+ }
}
func sendMessage(message: String) {
-
+ let encoded = message.data(using: .utf8)!.base64EncodedString()
+ let source = """
+ if (global.__iono_onMessage) {
+ const msg = (new Buffer('\(encoded)', 'base64')).toString('ascii');
+ global.__iono_onMessage(msg);
+ } else {
+ console.log("WARN: no __iono_onMessage defined");
+ }
+ """
+ evalNodeCode(source: source)
}
- func waitUntilStopped() {
+ func waitStopped() {
}
- func putModuleCode(moduleName: String, code: String) {
- __put_module_code(moduleName.cString(using: .utf8), code.cString(using: .utf8), __instance)
+ func putModuleCode(modName: String, code: String) {
+ __putModuleCodeNative(instance, modName.cString(using: .utf8),
+ code.cString(using: .utf8))
}
}