summaryrefslogtreecommitdiffstats
path: root/lib/peer.tcl
blob: e8e18be8ad27aee6f63d67dd59afdc03530c07ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
lappend auto_path "./vendor"

namespace eval ::Peers {}
set ::peersBlacklist [dict create]

proc ::addMatchesToShareStatements {shareStatementsVar matches} {
    upvar $shareStatementsVar shareStatements
    foreach m $matches {
        set pattern [dict get $m pattern]
        foreach match [Statements::findMatches $pattern] {
            set id [lindex [dict get $match __matcheeIds] 0]
            set clause [statement clause [Statements::get $id]]
            dictset add shareStatements $clause
        }
    }
}

proc ::peer {process {dieOnDisconnect false}} {
    namespace eval ::Peers::$process {
        variable connected true

        proc log {s} {
            variable process
            puts "$::thisProcess -> $process: $s"
        }

        # TODO: Handle die on disconnect (?)

        proc send {statements} {
            variable process
            Mailbox::share $::thisProcess $process $statements
        }
        proc receive {} {
            variable process
            Mailbox::receive $process $::thisProcess
        }
	proc clear {} {
            variable process
            Mailbox::clear $process $::thisProcess
	}

        proc share {shareStatements} {
            variable process
            variable prevShareStatements

            variable connected
            if {!$connected} { return }

            # Share.
            ::addMatchesToShareStatements shareStatements \
                [Statements::findMatches [list /someone/ wishes $process receives statements like /pattern/]]
            if {![info exists prevShareStatements] ||
                ([dictset size $prevShareStatements] > 0 ||
                 [dictset size $shareStatements] > 0)} {

                send [dictset entries $shareStatements]

                set prevShareStatements $shareStatements
            }
        }

        proc init {n shouldDieOnDisconnect} {
            variable process $n
            variable dieOnDisconnect $shouldDieOnDisconnect

            Mailbox::create $::thisProcess $process
            Mailbox::create $process $::thisProcess
        }
        init
    } $process $dieOnDisconnect
}