-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRxObserver.h
More file actions
147 lines (120 loc) · 4.75 KB
/
Copy pathRxObserver.h
File metadata and controls
147 lines (120 loc) · 4.75 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
#pragma once
#include <RxObserver/EventSource.h>
#include <RxObserver/ObserverPolicy.h>
#include <RxObserver/EventBase.h>
namespace BaseLib
{
template <typename T>
class RxEventsReturn
{
public:
virtual ~RxEventsReturn() {}
/**
* @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() = 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(T ) = 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(GeneralException ) = 0;
};
template <typename T>
class RxEventsSource
: public Concurrent::EventSource<RxEventsReturn<T>>
, public Templates::FactoryFunction0<RxEventsSource<T>>
{
private:
typedef RxEventsSource<T> Source;
typedef RxEventsReturn<T> EventType;
typedef std::shared_ptr<RxEventsReturn<T>> EventTypePtr;
typedef typename Concurrent::SubjectGroup<EventType>::Ptr SubjectGroupPtr;
public:
virtual ~RxEventsSource()
{
}
/**
* @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()
{
return subject_->template NextEvent<Source, bool>(&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(T t)
{
return subject_->template NextEvent<Source, bool, T>(t, &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(GeneralException exception)
{
return subject_->template NextEvent<Source, bool, GeneralException>(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());
ASSERT(observer);
// ---------------------------------------
// Subscribe to RxEvents
// ---------------------------------------
subscription = subject_-> template Subscribe<bool, T>(observer, &EventType::OnNext, policy);
subscriptions->Add(subscription);
subscription = subject_-> template Subscribe<bool, GeneralException>(observer, &EventType::OnError, policy);
subscriptions->Add(subscription);
subscription = subject_-> template Subscribe<bool>(observer, &EventType::OnComplete, policy);
subscriptions->Add(subscription);
return subscriptions;
}
virtual bool Initialize(SubjectGroupPtr subject)
{
ASSERT(subject);
subject_ = subject;
subject_->template Create<bool, T>(&EventType::OnNext);
subject_->template Create<bool>(&EventType::OnComplete);
subject_->template Create<bool, GeneralException>(&EventType::OnError);
return subject_ != nullptr;
}
virtual bool IsInitialized() const
{
return subject_ != nullptr;
}
static Concurrent::SubjectDescription DefaultDescription()
{
return Concurrent::SubjectDescription("RxEvents");
}
private:
SubjectGroupPtr subject_;
};
template <typename T>
class RxObserverNew
: public RxEventsReturn<T>
, public Concurrent::ObserverEventType<RxEventsReturn<T>, RxEventsSource<T>>
{
public:
RxObserverNew(Concurrent::SubjectDescription description = RxEventsSource<T>::DefaultDescription())
: Concurrent::ObserverEventType<RxEventsReturn<T>, RxEventsSource<T>>(RxEventsSource<T>::CreatePtr(), description)
{ }
virtual ~RxObserverNew()
{ }
};
}