forked from dxFeed/dxfeed-c-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEventSubscription.hpp
153 lines (107 loc) · 3.95 KB
/
EventSubscription.hpp
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* The contents of this file are subject to the Mozilla Public License Version
* 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Initial Developer of the Original Code is Devexperts LLC.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*/
#pragma once
#include <mutex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace dx {
struct SubscriptionData;
struct SymbolData {
std::wstring name{};
int refCount;
std::unordered_set<SubscriptionData*> subscriptions{};
dxf_event_data_t* lastEvents;
dxf_event_data_t* lastEventsAccessed;
static SymbolData* cleanup(SymbolData* dataArray);
static SymbolData* create(dxf_const_string_t name);
void storeLastSymbolEvent(dx_event_id_t eventId, dxf_const_event_data_t data);
};
enum class EventListenerVersion { Default = 1, V2 = 2 };
class ListenerContext {
union {
dxf_event_listener_t listener;
dxf_event_listener_v2_t listenerV2;
};
EventListenerVersion version;
void* userData;
public:
ListenerContext() = default;
using ListenerPtr = void*;
ListenerContext(ListenerPtr listener, EventListenerVersion version, void* userData) noexcept;
ListenerPtr getListener() const noexcept;
EventListenerVersion getVersion() const noexcept;
static ListenerContext createDummy(ListenerPtr listener);
void* getUserData() const noexcept;
friend bool operator==(const ListenerContext& listenerContext1, const ListenerContext& listenerContext2) {
return listenerContext1.getListener() == listenerContext2.getListener();
}
};
} // namespace dx
namespace std {
template <>
struct hash<dx::ListenerContext> {
std::size_t operator()(const dx::ListenerContext& lc) const noexcept {
return std::hash<dx::ListenerContext::ListenerPtr>{}(lc.getListener());
}
};
} // namespace std
namespace dx {
struct SubscriptionData {
unsigned event_types;
std::unordered_map<std::wstring, SymbolData*> symbols{};
std::unordered_set<ListenerContext> listeners{};
std::unordered_set<std::wstring> orderSources{};
dx_order_source_array_t rawOrderSources{};
dx_event_subscr_flag subscriptionFlags;
dxf_long_t time;
std::vector<dxf_const_string_t> symbolNames{};
void* connection_context; /* event subscription connection context */
static void free(SubscriptionData* subscriptionData);
static int closeEventSubscription(dxf_subscription_t subscriptionId, bool removeFromContext);
//Fills the non-special order sources array.
void fillRawOrderSources();
void clearRawOrderSources();
};
class EventSubscriptionConnectionContext {
dxf_connection_t connectionHandle;
std::recursive_mutex mutex{};
std::unordered_map<std::wstring, SymbolData*> symbols{};
std::unordered_set<SubscriptionData*> subscriptions{};
public:
static const std::unordered_set<std::wstring> specialOrderSources;
explicit EventSubscriptionConnectionContext(dxf_connection_t connectionHandle);
dxf_connection_t getConnectionHandle();
std::unordered_set<SubscriptionData*> getSubscriptions();
SymbolData* subscribeSymbol(dxf_const_string_t symbolName, SubscriptionData* owner);
void removeSymbolData(SymbolData* symbolData);
int unsubscribeSymbol(SymbolData* symbolData, SubscriptionData* owner);
SymbolData* findSymbol(dxf_const_string_t symbolName);
bool hasAnySymbol();
template <typename F>
auto process(F&& f) -> decltype(f(this)) {
std::lock_guard<std::recursive_mutex> lk(mutex);
return f(this);
}
void addSubscription(SubscriptionData* data);
void removeSubscription(SubscriptionData* data);
~EventSubscriptionConnectionContext();
};
} // namespace dx