Преглед изворни кода

Merge remote-tracking branch 'trio-vanilla/dev' into sync-trio-0.2.2

Deniz Cengiz пре 1 година
родитељ
комит
25d253507e

+ 1 - 1
CODE_OF_CONDUCT.md

@@ -59,7 +59,7 @@ representative at an online or offline event.
 ## Enforcement
 ## Enforcement
 
 
 Instances of abusive, harassing, or otherwise unacceptable behavior may be
 Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the Discord server admins. Please join our [Discord server](https://discord.gg/dbe5Twav8D) to contact
+reported to the Discord server admins. Please join our [Discord server](http://discord.diy-trio.org) to contact
 them directly for any enforcement issues. All complaints will be reviewed and
 them directly for any enforcement issues. All complaints will be reviewed and
 investigated promptly and fairly.
 investigated promptly and fairly.
 
 

+ 1 - 1
Config.xcconfig

@@ -1,5 +1,5 @@
 APP_DISPLAY_NAME = Trio
 APP_DISPLAY_NAME = Trio
-APP_VERSION = 0.2.0
+APP_VERSION = 0.2.2
 APP_BUILD_NUMBER = 1
 APP_BUILD_NUMBER = 1
 COPYRIGHT_NOTICE =
 COPYRIGHT_NOTICE =
 DEVELOPER_TEAM = ##TEAM_ID##
 DEVELOPER_TEAM = ##TEAM_ID##

+ 11 - 1
FreeAPS/Sources/APS/FetchGlucoseManager.swift

@@ -1,5 +1,6 @@
 import Combine
 import Combine
 import Foundation
 import Foundation
+import HealthKit
 import LoopKit
 import LoopKit
 import LoopKitUI
 import LoopKitUI
 import SwiftDate
 import SwiftDate
@@ -101,6 +102,14 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
         settingsManager.settings.uploadGlucose = cgmM.shouldSyncToRemoteService
         settingsManager.settings.uploadGlucose = cgmM.shouldSyncToRemoteService
     }
     }
 
 
+    private func updateManagerUnits(_ manager: CGMManagerUI?) {
+        let units = settingsManager.settings.units
+        let managerName = cgmManager.map { "\(type(of: $0))" } ?? "nil"
+        let loopkitUnits: HKUnit = units == .mgdL ? .milligramsPerDeciliter : .millimolesPerLiter
+        print("manager: \(managerName) is changing units to: \(loopkitUnits.description) ")
+        manager?.unitDidChange(to: loopkitUnits)
+    }
+
     func updateGlucoseSource(cgmGlucoseSourceType: CGMType, cgmGlucosePluginId: String, newManager: CGMManagerUI?) {
     func updateGlucoseSource(cgmGlucoseSourceType: CGMType, cgmGlucosePluginId: String, newManager: CGMManagerUI?) {
         // if changed, remove all calibrations
         // if changed, remove all calibrations
         if self.cgmGlucoseSourceType != cgmGlucoseSourceType || self.cgmGlucosePluginId != cgmGlucosePluginId {
         if self.cgmGlucoseSourceType != cgmGlucoseSourceType || self.cgmGlucosePluginId != cgmGlucosePluginId {
@@ -123,6 +132,8 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
             removeCalibrations()
             removeCalibrations()
         } else if self.cgmGlucoseSourceType == .plugin, cgmManager == nil, let rawCGMManager = rawCGMManager {
         } else if self.cgmGlucoseSourceType == .plugin, cgmManager == nil, let rawCGMManager = rawCGMManager {
             cgmManager = cgmManagerFromRawValue(rawCGMManager)
             cgmManager = cgmManagerFromRawValue(rawCGMManager)
+            updateManagerUnits(cgmManager)
+
         } else {
         } else {
             saveConfigManager()
             saveConfigManager()
         }
         }
@@ -152,7 +163,6 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
         else {
         else {
             return nil
             return nil
         }
         }
-
         return Manager.init(rawState: rawState)
         return Manager.init(rawState: rawState)
     }
     }
 
 

+ 69 - 6
FreeAPS/Sources/APS/OpenAPS/JavaScriptWorker.swift

@@ -1,11 +1,36 @@
 import Foundation
 import Foundation
 import JavaScriptCore
 import JavaScriptCore
 
 
+private let contextLock = NSRecursiveLock()
+
+extension String {
+    var lowercasingFirst: String { prefix(1).lowercased() + dropFirst() }
+    var uppercasingFirst: String { prefix(1).uppercased() + dropFirst() }
+    var camelCased: String {
+        guard !isEmpty else { return "" }
+        let parts = components(separatedBy: .alphanumerics.inverted)
+        let first = parts.first!.lowercasingFirst
+        let rest = parts.dropFirst().map(\.uppercasingFirst)
+        return ([first] + rest).joined()
+    }
+
+    var pascalCased: String {
+        guard !isEmpty else { return "" }
+        let parts = components(separatedBy: .alphanumerics.inverted)
+        let first = parts.first!.uppercasingFirst
+        let rest = parts.dropFirst().map(\.uppercasingFirst)
+        return ([first] + rest).joined()
+    }
+}
+
 final class JavaScriptWorker {
 final class JavaScriptWorker {
     private let processQueue = DispatchQueue(label: "DispatchQueue.JavaScriptWorker", attributes: .concurrent)
     private let processQueue = DispatchQueue(label: "DispatchQueue.JavaScriptWorker", attributes: .concurrent)
     private let virtualMachine: JSVirtualMachine
     private let virtualMachine: JSVirtualMachine
     private var contextPool: [JSContext] = []
     private var contextPool: [JSContext] = []
     private let contextPoolLock = NSLock()
     private let contextPoolLock = NSLock()
+    @SyncAccess(lock: contextLock) private var commonContext: JSContext? = nil
+    private var consoleLogs: [String] = []
+    private var logContext: String = ""
 
 
     init(poolSize: Int = 5) {
     init(poolSize: Int = 5) {
         virtualMachine = JSVirtualMachine()!
         virtualMachine = JSVirtualMachine()!
@@ -23,7 +48,10 @@ final class JavaScriptWorker {
             }
             }
         }
         }
         let consoleLog: @convention(block) (String) -> Void = { message in
         let consoleLog: @convention(block) (String) -> Void = { message in
-            debug(.openAPS, "JavaScript log: \(message)")
+            let trimmedMessage = message.trimmingCharacters(in: .whitespacesAndNewlines)
+            if !trimmedMessage.isEmpty {
+                self.consoleLogs.append("\(trimmedMessage)")
+            }
         }
         }
         context.setObject(consoleLog, forKeyedSubscript: "_consoleLog" as NSString)
         context.setObject(consoleLog, forKeyedSubscript: "_consoleLog" as NSString)
         return context
         return context
@@ -42,8 +70,37 @@ final class JavaScriptWorker {
         contextPoolLock.unlock()
         contextPoolLock.unlock()
     }
     }
 
 
+    // New method to flush aggregated logs
+    private func outputLogs() {
+        var outputLogs = consoleLogs.joined(separator: "\n").trimmingCharacters(in: .whitespacesAndNewlines)
+        consoleLogs.removeAll()
+
+        if outputLogs.isEmpty { return }
+
+        if logContext == "autosens.js" {
+            outputLogs = outputLogs.split(separator: "\n").map { logLine in
+                logLine.replacingOccurrences(
+                    of: "^[-+=x!]|u\\(|\\)|\\d{1,2}h$",
+                    with: "",
+                    options: .regularExpression
+                )
+            }.joined(separator: "\n")
+        }
+
+        if !outputLogs.isEmpty {
+            outputLogs.split(separator: "\n").forEach { logLine in
+                if !"\(logLine)".trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
+                    debug(.openAPS, "\(logContext): \(logLine)")
+                }
+            }
+        }
+    }
+
     @discardableResult func evaluate(script: Script) -> JSValue! {
     @discardableResult func evaluate(script: Script) -> JSValue! {
-        evaluate(string: script.body)
+        logContext = URL(fileURLWithPath: script.name).lastPathComponent
+        let result = evaluate(string: script.body)
+        outputLogs()
+        return result
     }
     }
 
 
     private func evaluate(string: String) -> JSValue! {
     private func evaluate(string: String) -> JSValue! {
@@ -63,15 +120,21 @@ final class JavaScriptWorker {
 
 
     func inCommonContext<Value>(execute: (JavaScriptWorker) -> Value) -> Value {
     func inCommonContext<Value>(execute: (JavaScriptWorker) -> Value) -> Value {
         let context = getContext()
         let context = getContext()
-        defer { returnContext(context) }
+        defer {
+            returnContext(context)
+            outputLogs()
+        }
         return execute(self)
         return execute(self)
     }
     }
 
 
     func evaluateBatch(scripts: [Script]) {
     func evaluateBatch(scripts: [Script]) {
-        let ctx = getContext()
-        defer { returnContext(ctx) } // Ensure the context is returned to the pool
+        let context = getContext()
+        defer {
+            // Ensure the context is returned to the pool
+            returnContext(context)
+        }
         scripts.forEach { script in
         scripts.forEach { script in
-            ctx.evaluateScript(script.body)
+            context.evaluateScript(script.body)
         }
         }
     }
     }
 }
 }

+ 2 - 2
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -971,11 +971,11 @@ final class OpenAPS {
 
 
     private func middlewareScript(name: String) -> Script? {
     private func middlewareScript(name: String) -> Script? {
         if let body = storage.retrieveRaw(name) {
         if let body = storage.retrieveRaw(name) {
-            return Script(name: "Middleware", body: body)
+            return Script(name: name, body: body)
         }
         }
 
 
         if let url = Foundation.Bundle.main.url(forResource: "javascript/\(name)", withExtension: "") {
         if let url = Foundation.Bundle.main.url(forResource: "javascript/\(name)", withExtension: "") {
-            return Script(name: "Middleware", body: try! String(contentsOf: url))
+            return Script(name: name, body: try! String(contentsOf: url))
         }
         }
 
 
         return nil
         return nil

+ 1 - 1
README.md

@@ -63,7 +63,7 @@ Instructions in greater detail, but not Trio-specific:
 
 
 # Documentation
 # Documentation
 
 
-[Discord Trio - Server ](https://discord.gg/KepAG6RdYZ)
+[Discord Trio - Server ](http://discord.diy-trio.org)
 
 
 [Trio documentation](https://docs.diy-trio.org/en/latest/)
 [Trio documentation](https://docs.diy-trio.org/en/latest/)