summaryrefslogtreecommitdiffstats
path: root/src/gui/CoreConnector.vala
blob: fdd74ee2d2b58dcb7b0e1ad2fba9a1a875ac1ac3 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
public class CoreConnector {
  unowned Thread thread;
  bool running;
  
  Erl.Node node;
  Erl.Connection con;
  Erl.Term self;
  
  Roster roster;
  
  private class TermStore {
    public Erl.Term term;
  }
  
  static construct {
    Erl.init();
  }
  
  public CoreConnector(Roster roster0) {
    running = false;
    roster = roster0;
  }
  
  public bool start() {
    if(running)
      return true;
    
    running = true;
    
    node = Erl.Node("ephraim-gtk", "magiccookie", 0);
    con = node.connect("ephraim-core@avalon.local");
    
    self = Erl.mk_self_pid(node);
    
    con.reg_send("ephraim", Erl.format("{register_ui,~w}", self));
    
    try {
      thread = Thread.create(receive, true);
      return true;
    } catch(ThreadError e) {
      return false;
    }
  }
  
  public void stop() {
    if(!running)
      return;
    
    running = false;
    thread.join();
    
    con.reg_send("ephraim", Erl.format("{unregister_ui,~w}", self));
  }
  
  
  private void* receive() {
    while(running) {
      TermStore response = new TermStore();
      Erl.ReceiveType ret = con.receive(out response.term, 1000);
      
      switch(ret) {
      case Erl.ReceiveType.ERROR:
        if(Erl.errno == Erl.Error.TIMEDOUT)
          break;
        
        running = false;
        break;
      case Erl.ReceiveType.TICK:
        // Do nothing
        break;
      case Erl.ReceiveType.MSG:
        Idle.add(() => {handleTerm(response); return false;});
        break;
      }
    }
    
    return null;
  }
  
  private Erl.Term? match(string pattern, Erl.Term term) {
    Erl.Term pattern_term = Erl.format(pattern);
    
    if(pattern_term.match(term) != 0)
      return pattern_term;
    else
      return null;
  }
  
  private void handleTerm(TermStore store) {
    unowned Erl.Term term = store.term; 
    Erl.Term match_term;
    
    if((match_term = match("{roster_update,JID,Resources}", term)) != null) {
      Erl.Term JID_term = match_term.var_content("JID");
      string JID = ((string)JID_term.bin_ptr()).ndup(JID_term.bin_size());
      
      roster.update_contact(new Contact(JID));
    }
    else {
      Erl.print_term(stdout, term);
      stdout.printf("\n");
    }
  }
}