-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKeyValueRxObserver.h
More file actions
157 lines (129 loc) · 5.12 KB
/
Copy pathKeyValueRxObserver.h
File metadata and controls
157 lines (129 loc) · 5.12 KB
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
154
155
156
157
#pragma once
#include "RxObserver/IncludeExtLibs.h"
#include "RxObserver/EventSource.h"
#include "RxObserver/EventBase.h"
#include "RxObserver/SubjectDescription.h"
namespace BaseLib {
template <typename K, typename V>
class KeyValueRxEvents
{
public:
virtual ~KeyValueRxEvents()
{ }
/**
* @brief OnCompleted Notifies the Observer that the Observable has finished sending push-based notifications.
* The Observable will not call this closure if it calls onError.
*/
virtual bool OnComplete(K key) = 0;
/**
* @brief Provides the Observer with new data. The Observable calls this closure 1 or more times, unless it
* calls onError in which case this closure may never be called. The Observable will not call this closure again
* after it calls either onCompleted or onError.
*/
virtual bool OnNext(K key, V value) = 0;
/**
* @brief OnError Notifies the Observer that the Observable has experienced an error condition.
* If the Observable calls this closure, it will not thereafter call onNext or onCompleted.
*/
virtual bool OnError(K key, GeneralException) = 0;
};
template <typename K, typename V>
class KeyValueRxEventsSource
: public Concurrent::EventSource<KeyValueRxEvents<K, V>>
, public Templates::FactoryFunction0<KeyValueRxEventsSource<K, V>>
{
private:
typedef KeyValueRxEventsSource<K, V> Source;
typedef KeyValueRxEvents<K, V> EventType;
typedef std::shared_ptr<KeyValueRxEvents<K, V>> EventTypePtr;
typedef typename Concurrent::SubjectGroup<EventType>::Ptr SubjectGroupPtr;
public:
virtual ~KeyValueRxEventsSource()
{ }
/**
* @brief OnCompleted Notifies the Observer that the Observable has finished sending push-based notifications.
* The Observable will not call this closure if it calls onError.
*/
Concurrent::Event::Ptr Complete(K key)
{
return subject_->template NextEvent<Source, bool, K>(key, &EventType::OnComplete, this);
}
/**
* @brief Provides the Observer with new data. The Observable calls this closure 1 or more times, unless it
* calls onError in which case this closure may never be called. The Observable will not call this closure again
* after it calls either onCompleted or onError.
*/
Concurrent::Event::Ptr Next(K key, V value)
{
return subject_->template NextEvent<Source, bool, K, V>(key, value, &EventType::OnNext, this);
}
/**
* @brief OnError Notifies the Observer that the Observable has experienced an error condition.
* If the Observable calls this closure, it will not thereafter call onNext or onCompleted.
*/
Concurrent::Event::Ptr Error(K key, GeneralException exception)
{
return subject_->template NextEvent<Source, bool, K, GeneralException>(
key,
exception,
&EventType::OnError,
this
);
}
/**
* Subscribe called by observer
*/
virtual Concurrent::Subscriptions::Ptr Subscribe(
EventTypePtr observer,
Concurrent::ObserverPolicy policy = Concurrent::ObserverPolicy::Default()) const
{
Concurrent::Subscriptions::Ptr subscriptions(new Concurrent::Subscriptions());
Concurrent::Subscription::Ptr subscription;
ASSERT(IsInitialized());
// ---------------------------------------
// Subscribe to EventType
// ---------------------------------------
subscription = subject_->template Subscribe<bool, K>(observer, &EventType::OnComplete, policy);
subscriptions->Add(subscription);
subscription = subject_->template Subscribe<bool, K, V>(observer, &EventType::OnNext, policy);
subscriptions->Add(subscription);
subscription = subject_->template Subscribe<bool, K, GeneralException>(observer, &EventType::OnError, policy);
subscriptions->Add(subscription);
return subscriptions;
}
virtual bool Initialize(SubjectGroupPtr subject)
{
subject_ = subject;
subject_->template Create<bool, K>(&EventType::OnComplete);
subject_->template Create<bool, K, V>(&EventType::OnNext);
subject_->template Create<bool, K, GeneralException>(&EventType::OnError);
return subject_ != nullptr;
}
virtual bool IsInitialized() const
{
return subject_ != nullptr;
}
static Concurrent::SubjectDescription DefaultDescription()
{
return Concurrent::SubjectDescription("KeyValueRxEvents");
}
private:
SubjectGroupPtr subject_;
};
template <typename K, typename V>
class KeyValueRxObserver
: public KeyValueRxEvents<K, V>
, public Concurrent::ObserverEventType<KeyValueRxEvents<K, V>, KeyValueRxEventsSource<K, V>>
{
public:
KeyValueRxObserver(Concurrent::SubjectDescription description = KeyValueRxEventsSource<K, V>::DefaultDescription())
: Concurrent::ObserverEventType<KeyValueRxEvents<K, V>, KeyValueRxEventsSource<K, V>>
(
KeyValueRxEventsSource<K, V>::CreatePtr(),
description
)
{ }
virtual ~KeyValueRxObserver()
{ }
};
}