@craft-native/ios 0.0.244 → 0.0.246

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1376,23 +1376,32 @@ final class CraftWebAudio {
1376
1376
  /// JavaScript, before its bundle runs.
1377
1377
  func install(in context: JSContext) {
1378
1378
  script = context
1379
+ // The graph lives on the main thread. A script on its own thread
1380
+ // (CraftNativeScriptThread) reaches it there, waiting for the answer
1381
+ // its synchronous calls return; arguments are read off the JSValues
1382
+ // where the script runs.
1379
1383
  let open: @convention(block) (Int, Double) -> NSDictionary? = { [weak self] id, rate in
1380
- self?.open(id, requestedRate: rate) as NSDictionary?
1384
+ CraftNativeScriptThread.onMain { self?.open(id, requestedRate: rate) as NSDictionary? }
1381
1385
  }
1382
1386
  let send: @convention(block) (JSValue) -> Void = { [weak self] batch in
1383
- self?.receive(batch.toArray() ?? [])
1387
+ let commands = batch.toArray() ?? []
1388
+ CraftNativeScriptThread.onMain { self?.receive(commands) }
1384
1389
  }
1385
1390
  let time: @convention(block) (Int) -> Double = { [weak self] id in
1386
- self?.contexts[id]?.graph.currentTime ?? 0
1391
+ CraftNativeScriptThread.onMain { self?.contexts[id]?.graph.currentTime ?? 0 }
1387
1392
  }
1388
1393
  let read: @convention(block) (Int, Int, String) -> Double = { [weak self] contextId, nodeId, key in
1389
- self?.read(contextId, nodeId, key) ?? .nan
1394
+ CraftNativeScriptThread.onMain { self?.read(contextId, nodeId, key) ?? .nan }
1390
1395
  }
1391
1396
  let state: @convention(block) (Int, String) -> Bool = { [weak self] id, state in
1392
- self?.setState(id, state) ?? false
1397
+ CraftNativeScriptThread.onMain { self?.setState(id, state) ?? false }
1393
1398
  }
1394
1399
  let buffer: @convention(block) (Int, Double, Int, JSValue) -> Bool = { [weak self] id, rate, length, channels in
1395
- self?.storeBuffer(id, rate, length, channels) ?? false
1400
+ // The samples are copied out of the script's typed arrays where
1401
+ // the script runs, then kept beside the graph.
1402
+ guard let data = Self.copyBuffer(rate, length, channels) else { return false }
1403
+ CraftNativeScriptThread.onMain { self?.buffers[id] = data }
1404
+ return true
1396
1405
  }
1397
1406
  context.setObject(open, forKeyedSubscript: "craftNativeAudioOpen" as NSString)
1398
1407
  context.setObject(send, forKeyedSubscript: "craftNativeAudioSend" as NSString)
@@ -1637,10 +1646,10 @@ final class CraftWebAudio {
1637
1646
  }
1638
1647
 
1639
1648
  /// An AudioBuffer's channels, copied straight out of its Float32Arrays.
1640
- private func storeBuffer(_ id: Int, _ rate: Double, _ length: Int, _ channels: JSValue) -> Bool {
1641
- guard length > 0, rate > 0, let context = JSContext.current() else { return false }
1649
+ private static func copyBuffer(_ rate: Double, _ length: Int, _ channels: JSValue) -> CraftAudioBufferData? {
1650
+ guard length > 0, rate > 0, let context = JSContext.current() else { return nil }
1642
1651
  let count = Int(channels.objectForKeyedSubscript("length")?.toInt32() ?? 0)
1643
- guard count > 0 else { return false }
1652
+ guard count > 0 else { return nil }
1644
1653
  let data = CraftAudioBufferData(sampleRate: rate, length: length, channelCount: count)
1645
1654
  let script = context.jsGlobalContextRef
1646
1655
  for index in 0..<count {
@@ -1651,8 +1660,7 @@ final class CraftWebAudio {
1651
1660
  let available = JSObjectGetTypedArrayLength(script, object, nil)
1652
1661
  data.channels[index].update(from: bytes.assumingMemoryBound(to: Float.self), count: min(length, available))
1653
1662
  }
1654
- buffers[id] = data
1655
- return true
1663
+ return data
1656
1664
  }
1657
1665
 
1658
1666
  // MARK: Notices
@@ -1675,8 +1683,8 @@ final class CraftWebAudio {
1675
1683
  }
1676
1684
  }
1677
1685
  }
1678
- guard !ended.isEmpty else { return }
1679
- script?.objectForKeyedSubscript("__craftNativeAudioEvents")?.call(withArguments: [ended])
1686
+ guard !ended.isEmpty, let script else { return }
1687
+ CraftNativeScriptThread.run { script.objectForKeyedSubscript("__craftNativeAudioEvents")?.call(withArguments: [ended]) }
1680
1688
  }
1681
1689
 
1682
1690
  // MARK: Tests