summaryrefslogtreecommitdiff
path: root/docs/design/libwatch/class_diagram.plantuml
blob: 600bcfa4e839ef111696687227dd359497ba2799 (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
105
106
107
108
109
110
111
@startuml
skinparam titleFontSize 24
skinparam defaultFontSize 16
title NFSTrace: libwatch class diagram

abstract class AbstractProtocol #Aquamarine {
  + commandsAmount: const std::size_t
  + name: const std::string
  + AbstractProtocol(name: const std::string&, commandsAmount: std::size_t)
  + {abstract} commandName(std::size_t commandId): const char * = 0
}

class NFSv3Protocol #Aquamarine {
  + NFSv3Protocol()
  + {abstract} commandName(std::size_t commandId): const char *
}

class NFSv4Protocol #Aquamarine {
  + NFSv4Protocol()
  + {abstract} commandName(std::size_t commandId): const char *
}

AbstractProtocol <|-- NFSv3Protocol
AbstractProtocol <|-- NFSv4Protocol

class CommandsStatistics {
  + commands: std::vector<std::size_t>
}

class WatchAnalyzer {
  - _userGUI: UserGUI
  - _protocols: std::vector<AbstractProtocol*>
  + {abstract} onCommand(): void
  + {abstract} onUnixSignal(): void
}

class UserGUI << thread >> {
  - _isRunning: std::atomic<bool>
  - _shouldRefresh: std::atomic<bool>
  - _statisticsMutex: std::mutex
  - _statisticsContainer: std::unordered_map<AbstractProtocol*, CommandsStatistics>
  - _activeProtocol: AbstractProtocol&
  - _mainWindow: MainWindow
  - _headerWindow: HeaderWindow
  - _statisticsWindow: StatisticsWindow
  + UserGUI(protocols: std::vector<AbstractProtocol *>&)
  + incrementCommand(protocol: const AbstractProtocol&, commandId: std::size_t)
  + refresh()
  - run()
  - selectProtocol(protocol: const ActiveProtocol&)
}

note right of UserGUI
  <b>_statisticsContainer/_statisticsMutex</b>
  are used to thread-safely pass statistics from
  analyzer's thread to GUI's one;
  <b>run()</b> is a thread-function where GUI is to
  be created/[re-]drawn/destroyed, keyboard events are to
  be handled and incoming statistics delta is to be applied;
  <b>selectProtocol()</b> is to be called internally when
  a user changes active protocol;
  <b>incrementCommand()</b> is to be called from analyzer
  to update statistics on command detection;
  <b>refresh()</b> is to be called from analyzer
  to completely redraw GUI (e.g. on SIGCONT) -
  this method just sets <b>_shouldRefresh</b> to <b>true</b>
  but actual refresh is made in <b>run()</b>.
end note

class MainWindow #Khaki {
  - _handle: WINDOW*
}

class HeaderWindow #Khaki {
  - _handle: WINDOW*
  - _activeProtocol: const AbstractProtocol&
  + HeaderWindow(protocols: std::vector<AbstractProtocol *>&, activeProtocol: const AbstractProtocol&)
  + selectProtocol(protocol: const AbstractProtocol&)
  + refresh()
}

class StatisticsWindow #Khaki {
  - _handle: WINDOW*
  - _activeProtocol: const AbstractProtocol&
  - _statisticsContainer: const CommandsStatistics&
  - _scrollOffsets: std::unordered_map<AbstractProtocol*, std::size_t>
  + StatisticsWindow(activeProtocol: const AbstractProtocol&, statisticsContainer: const CommandsStatistics&)
  + selectProtocol(protocol: const AbstractProtocol&)
  + update()
  + scroll(increment: int)
  + refresh()
}

note top of StatisticsWindow
  <b>selectProtocol()</b> is to be called when a protocol is changed;
  <b>update()</b> is to be called to update statistics data;
  <b>scroll()</b> is to be called to scroll statistics data;
  <b>refresh()</b> is to be called to completely redraw window.
end note

WatchAnalyzer "1" *-- "1" UserGUI
WatchAnalyzer "1" *-- "*" AbstractProtocol
UserGUI "1" *-- "*" AbstractProtocol
UserGUI "1" *-- "1" MainWindow
UserGUI "1" *-- "1" HeaderWindow
UserGUI "1" *-- "1" StatisticsWindow
UserGUI "1" *-- "*" CommandsStatistics
HeaderWindow "1" o-- "1" AbstractProtocol
StatisticsWindow "1" o-- "1" CommandsStatistics
StatisticsWindow "1" o-- "1" AbstractProtocol
@enduml