From 2f83d0ef629d9c37c396739e6e901ba88c2b429a Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sat, 11 Jun 2022 21:04:12 -0500 Subject: [PATCH] seperate dataspaces for core and friends --- protocol.prs | 11 ++++++++ src/protocol.nim | 27 ++++++++++++++++--- src/syndicate_actor_tox.nim | 53 ++++++++++++++++++++++++++++++------- tox.config-example.pr | 29 ++++++++++++++++++++ 4 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 tox.config-example.pr diff --git a/protocol.prs b/protocol.prs index 1f158e1..957c140 100644 --- a/protocol.prs +++ b/protocol.prs @@ -10,6 +10,17 @@ Address =
. Name = . +Connection = =none / =tcp / =udp . +Status = . + StatusMessage = . +Typing = . + +; Asserted by the core on a friend request. +FriendRequest = . + +; Asserted to the core to accept a friend request. +FriendAccept = . + BootstrapNode = . diff --git a/src/protocol.nim b/src/protocol.nim index 351a707..7eb69d0 100644 --- a/src/protocol.nim +++ b/src/protocol.nim @@ -6,6 +6,10 @@ type Name* {.preservesRecord: "name".} = object `name`*: string + FriendRequest* {.preservesRecord: "request".} = object + `key`*: seq[byte] + `msg`*: string + FriendDataspace*[E] {.preservesRecord: "friend".} = ref object `publicKey`*: seq[byte] `entity`*: Preserve[E] @@ -17,6 +21,8 @@ type `publicKey`*: seq[byte] `entity`*: Preserve[E] + Typing* {.preservesRecord: "typing".} = object + BootstrapNode* {.preservesRecord: "bootstrap".} = object `publicKey`*: string `host`*: string @@ -25,6 +31,14 @@ type StatusMessage* {.preservesRecord: "status-message".} = object `msg`*: string + Status* {.preservesRecord: "status".} = object + `status`*: Connection + + FriendAccept* {.preservesRecord: "accept".} = object + `key`*: seq[byte] + + `Connection`* {.preservesOr, pure.} = enum + `none`, `tcp`, `udp` CoreVersion* {.preservesRecord: "core".} = object `major`*: int `minor`*: int @@ -36,9 +50,16 @@ proc `$`*[E](x: FriendDataspace[E] | ToxDataspace[E]): string = proc encode*[E](x: FriendDataspace[E] | ToxDataspace[E]): seq[byte] = encode(toPreserve(x, E)) -proc `$`*(x: Name | Address | BootstrapNode | StatusMessage | CoreVersion): string = +proc `$`*(x: Name | FriendRequest | Address | Typing | BootstrapNode | + StatusMessage | + Status | + FriendAccept | + CoreVersion): string = `$`(toPreserve(x)) -proc encode*(x: Name | Address | BootstrapNode | StatusMessage | CoreVersion): seq[ - byte] = +proc encode*(x: Name | FriendRequest | Address | Typing | BootstrapNode | + StatusMessage | + Status | + FriendAccept | + CoreVersion): seq[byte] = encode(toPreserve(x)) diff --git a/src/syndicate_actor_tox.nim b/src/syndicate_actor_tox.nim index 0e99b83..75b6a52 100644 --- a/src/syndicate_actor_tox.nim +++ b/src/syndicate_actor_tox.nim @@ -45,13 +45,12 @@ type core: Tox statusCounts: array[3, int] handles: CoreHandles - friendRequests: Table[toxcore.PublicKey, Handle] - friendEntities: seq[FriendEntity] + friends: Table[Friend, FriendEntity] proc init(e: Entity; turn: var Turn; parent: Ref): Handle = assert e.facet.isNil e.facet = turn.facet - e.ds = newRef(turn, parent.target) + e.ds = newDataspace(turn) proc initCore(entity: CoreEntity; turn: var Turn; parentRef: Ref) = assert entity.core.isNil @@ -123,17 +122,53 @@ proc initCore(entity: CoreEntity; turn: var Turn; parentRef: Ref) = entity.handles.statusMessage = publish(turn, entity.ds, StatusMessage(msg: entity.core.statusMessage)) block: # Friends initialization - var friendNums = entity.core.friends - entity.friendEntities.setLen(friendNums.len) - for fn in friendNums: + proc createFriend(turn: var Turn; fn: Friend) = var fe = new FriendEntity discard init(fe, turn, entity.ds) discard publish(turn, entity.ds, FriendDataspace[Ref]( publicKey: entity.core.publicKey(fn).bytes.toSeq, entity: fe.ds.embed)) - if fn.int > entity.friendEntities.len: - entity.friendEntities.setLen(fn.int.succ) - entity.friendEntities[int fn] = fe + fe.handles.name = publish(turn, fe.ds, Name(name: entity.core.name(fn))) + entity.friends[fn] = fe + + for fn in entity.core.friends: createFriend(turn, fn) + + entity.core.onSelfConnectionStatus do (status: toxcore.Connection): + run(entity.facet) do (turn: var Turn): + let conn = case status + of TOX_CONNECTION_NONE: protocol.Connection.none + of TOX_CONNECTION_TCP: protocol.Connection.tcp + of TOX_CONNECTION_UDP: protocol.Connection.udp + replace(turn, entity.ds, entity.handles.connectionStatus, + Status(status: conn)) + + template update[T](fe: FriendEntity; h: var Handle; a: T) = + run(fe.facet) do (turn: var Turn): replace(turn, fe.ds, h, a) + + entity.core.onFriendName do (num: Friend; name: string): + let fe = entity.friends[num] + update(fe, fe.handles.name, Name(name: name)) + + entity.core.onFriendStatusMessage do (num: Friend; msg: string): + let fe = entity.friends[num] + update(fe, fe.handles.statusMessage, StatusMessage(msg: msg)) + + entity.core.onFriendTyping do (num: Friend; typing: bool): + let fe = entity.friends[num] + if typing: + update(fe, fe.handles.typing, Typing()) + else: + run(fe.facet) do (turn: var Turn): + retract(turn, fe.handles.typing) + + entity.core.onFriendRequest do (pk: PublicKey; msg: string): + run(entity.facet) do (turn: var Turn): + let reqHandle = publish(turn, entity.ds, + FriendRequest(key: pk.bytes.toSeq, msg: msg)) + onPublish(turn, entity.ds, ?FriendAccept(key: pk.bytes.toSeq)) do: + createFriend(turn, entity.core.addFriendNoRequest(pk)) + retract(turn, reqHandle) + # TODO: stop watching for the accept assertion var alive: bool setControlCHook do: diff --git a/tox.config-example.pr b/tox.config-example.pr new file mode 100644 index 0000000..569e147 --- /dev/null +++ b/tox.config-example.pr @@ -0,0 +1,29 @@ +> + + +? ?tox> [ + $config ? ?notifier> [ + $tox [ + + ? $core [ + ?
$log ! + ? [ + $notifier ! + + ] + ? $friend [ + $notifier ! + ? [ + $notifier ! + ? [ $notifier ! ] + ] + ] + ] + ] + ] +]