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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Buttplug Rust Source Code File - See https://buttplug.io for more info.
//
// Copyright 2016-2020 Nonpolynomial Labs LLC. All rights reserved.
//
// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
// for full license information.
//! Handling of remote message pairing and future resolution.
use crate::;
use HashMap;
/// Message sorting and pairing for remote client connectors.
///
/// In order to create reliable connections to remote systems, we need a way to
/// maintain message coherence. We expect that whenever a client sends the
/// server a request message, the server will always send back a response
/// message.
///
/// In the [embedded][crate::connector::ButtplugInProcessClientConnector] case,
/// where the client and server are in the same process, we can simply use
/// execution flow to match the client message and server response. However,
/// when going over IPC or network, we have to wait to hear back from the
/// server. To match the outgoing client request message with the incoming
/// server response message in the remote case, we use the `id` field of
/// [ButtplugMessage]. The client's request message will have a server response
/// with a matching index. Any message that comes from the server without an
/// originating client message
/// ([DeviceAdded][crate::core::messages::DeviceAdded],
/// [Log][crate::core::messages::Log], etc...) will have an `id` of 0 and is
/// considered an *event*, meaning something happened on the server that was not
/// directly tied to a client request.
///
/// The ClientConnectionMessageSorter does two things to facilitate this
/// matching:
///
/// - Creates and keeps track of the current message `id`, as a [u32]
/// - Manages a [HashMap] of indexes to resolvable futures.
///
/// Whenever a remote connector sends a [ButtplugMessage], it first puts it
/// through its [ClientConnectorMessageSorter] to fill in the message `id`.
/// Similarly, when a [ButtplugMessage] is received, it comes through the
/// sorter, with one of 3 outcomes:
///
/// - If there is a future with matching `id` waiting on a response, it resolves
/// that future using the incoming message
/// - If the message `id` is 0, the message is emitted as an *event*.
/// - If the message `id` is not zero but there is no future waiting, the
/// message is dropped and an error is emitted.
///