seperate dataspaces for core and friends

This commit is contained in:
Emery Hemingway 2022-06-11 21:04:12 -05:00
parent 389fd04c4a
commit 2f83d0ef62
4 changed files with 108 additions and 12 deletions

View File

@ -10,6 +10,17 @@ Address = <address @text string> .
Name = <name @name string> .
Connection = =none / =tcp / =udp .
Status = <status @status Connection> .
StatusMessage = <status-message @msg string> .
Typing = <typing> .
; Asserted by the core on a friend request.
FriendRequest = <request @key bytes @msg string> .
; Asserted to the core to accept a friend request.
FriendAccept = <accept @key bytes> .
BootstrapNode = <bootstrap @publicKey string @host string @port int> .

View File

@ -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))

View File

@ -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:

29
tox.config-example.pr Normal file
View File

@ -0,0 +1,29 @@
<require-service <daemon tox_bot>>
<daemon tox_bot {
argv: "/home/repo/syndicate/syndicate_actor_tox/syndicate_actor_tox"
dir: "/home/repo/syndicate/syndicate_actor_tox"
protocol: text/syndicate
clearEnv: #t
}>
? <service-object <daemon tox_bot> ?tox> [
$config ? <service-object <daemon freedesktop_notifier> ?notifier> [
$tox [
<bootstrap "6EF679EBD205E8DF9B6975D21CD157D046287700CADDF86F94B7ED243DC26A30" "20a:c3d2:8cf8:f8e5:80fe:9194:3800:87e6" 33445>
? <tox ?pk ?core> $core [
? <address ?addr> $log ! <log "-" { line: ["tox address" $addr] }>
? <request ?pk ?msg> [
$notifier ! <notify "friend request" $msg 0 Low>
<accept $pk>
]
? <friend ?pk ?friend> $friend [
$notifier ! <notify "new friend" $pk 0 Low>
? <name ?name> [
$notifier ! <notify "friend name" $name 0 Low>
? <status-message ?msg> [ $notifier ! <notify $name $msg 0 Low> ]
]
]
]
]
]
]