~ehmry/nim_tox

343e0ed6dd52dd8f6d0c68e5ae9818fb6e791d75 — Emery Hemingway 2 months ago 97b3dfc syndicate
Add Syndicate actor
1 files changed, 53 insertions(+), 0 deletions(-)

A src/toxcore/facets.nim
A src/toxcore/facets.nim => src/toxcore/facets.nim +53 -0
@@ 0,0 1,53 @@
# SPDX-License-Identifier: GPL-3.0-or-later

import std/[monotimes]
import preserves, preserves/records
import syndicate, syndicate/drivers/timers
import toxcore

proc toPreserveHook*(key: PublicKey): Preserve = %key.bytes

proc fromPreserveHook*(result: var PublicKey; prs: Preserve) =
  if prs.kind == pkByteString and prs.bytes.len == result.bytes.len:
    for i in 0..<result.bytes.len: result.bytes[i] = prs.bytes[i]
  else:
    raise newException(ValueError, "not a preserved PublicKey: " & $prs)

const
  SelfConnectionStatus* = RecordClass(label: symbol"toxSelfConnectionStatus", arity: 1)
  ConnectionStatus* = RecordClass(label: symbol"toxConnectionStatus", arity: 2)
  StatusMessage* = RecordClass(label: symbol"toxStatusMessage", arity: 2)
  FriendMessage* = RecordClass(label: symbol"toxFriendMessage", arity: 3)

type BootProc* = proc (facet: Facet) {.gcsafe.}

proc toxActor*(tox: sink Tox): BootProc =
  ## Spawn a Syndicate actor that takes control of a ``Tox`` instance.
  ## Requires a timer driver that responds to ``TimeLaterThan``.
  var tox = tox
  proc bootProc(facet: Facet) =
    proc getCurrentFacet(): Facet {.inject, used.} = facet

    spawn "tox":
      field(deadline, MonoTime, getMonoTime())
      onAsserted(TimeLaterThan % deadline.get):
        deadline.set getMonoTime() + tox.iterationInterval
        iterate tox

      during(Observe % (SelfConnectionStatus % `?_`)):
        tox.onSelfConnectionStatus do (conn: Connection):
          react: assert: SelfConnectionStatus % conn

      during(Observe % (ConnectionStatus.init(`?_`, `?_`))):
        tox.onFriendConnectionStatus do (friend: Friend; conn: Connection):
          react: assert: ConnectionStatus.init(tox.publicKey(friend), conn)

      during(Observe % (StatusMessage.init(`?_`, `?_`))):
        tox.onFriendStatusMessage do (friend: Friend; msg: string):
          react: assert: StatusMessage.init(tox.publicKey(friend), msg)

      during(Observe % (FriendMessage.init(`?_`, `?_`, `?_`))):
        tox.onFriendMessage do (f: Friend; msg: string; kind: MessageType):
          send: FriendMessage.init(tox.publicKey(f), msg, kind)

  result = bootProc