1// SMLooper.cpp
2
3#include <Message.h>
4
5#include "SMLooper.h"
6#include "SMMessages.h"
7
8// SMLooper
9
10// constructor
11SMLooper::SMLooper()
12		: BLooper(NULL, B_NORMAL_PRIORITY, 1),
13		  fUnblockTime(0),
14		  fReplyDelay(0),
15		  fDeliveryTime(-1),
16		  fReplyTime(-1)
17{
18}
19
20// destructor
21SMLooper::~SMLooper()
22{
23}
24
25// MessageReceived
26void
27SMLooper::MessageReceived(BMessage *message)
28{
29	switch (message->what) {
30		case MSG_BLOCK:
31		{
32			bigtime_t now = system_time();
33			if (now < fUnblockTime) {
34				// port capacity is 1 => the following message blocks the
35				// port until return from MessageReceived().
36				PostMessage(MSG_UNBLOCK, this);
37				snooze_until(fUnblockTime, B_SYSTEM_TIMEBASE);
38			}
39			break;
40		}
41		case MSG_UNBLOCK:
42			break;
43		case MSG_TEST:
44			SetDeliveryTime(system_time());
45			if (fReplyDelay > 0)
46				snooze(fReplyDelay);
47			message->SendReply(MSG_REPLY);
48			break;
49		case MSG_REPLY:
50			fReplyTime = system_time();
51			break;
52		default:
53			BLooper::MessageReceived(message);
54			break;
55	}
56}
57
58// BlockUntil
59void
60SMLooper::BlockUntil(bigtime_t unblockTime)
61{
62	fUnblockTime = unblockTime;
63	PostMessage(MSG_BLOCK, this);
64}
65
66// SetReplyDelay
67void
68SMLooper::SetReplyDelay(bigtime_t replyDelay)
69{
70	fReplyDelay = replyDelay;
71}
72
73// ReplyDelay
74bigtime_t
75SMLooper::ReplyDelay() const
76{
77	return fReplyDelay;
78}
79
80// DeliverySuccess
81bool
82SMLooper::DeliverySuccess() const
83{
84	return (fDeliveryTime >= 0);
85}
86
87// SetDeliveryTime
88void
89SMLooper::SetDeliveryTime(bigtime_t deliveryTime)
90{
91	fDeliveryTime = deliveryTime;
92}
93
94// DeliveryTime
95bigtime_t
96SMLooper::DeliveryTime() const
97{
98	return fDeliveryTime;
99}
100
101// ReplySuccess
102bool
103SMLooper::ReplySuccess() const
104{
105	return (fReplyTime >= 0);
106}
107
108// SetReplyTime
109void
110SMLooper::SetReplyTime(bigtime_t replyTime)
111{
112	fReplyTime = replyTime;
113}
114
115// ReplyTime
116bigtime_t
117SMLooper::ReplyTime() const
118{
119	return fReplyTime;
120}
121
122
123// SMHandler
124
125// constructor
126SMHandler::SMHandler()
127		 : BHandler()
128{
129}
130
131// MessageReceived
132void
133SMHandler::MessageReceived(BMessage *message)
134{
135	switch (message->what) {
136		case MSG_TEST:
137			if (SMLooper *looper = dynamic_cast<SMLooper*>(Looper())) {
138				looper->SetDeliveryTime(system_time());
139				if (looper->ReplyDelay() > 0)
140					snooze(looper->ReplyDelay());
141			}
142			message->SendReply(MSG_REPLY);
143			break;
144		case MSG_REPLY:
145			if (SMLooper *looper = dynamic_cast<SMLooper*>(Looper()))
146				looper->SetReplyTime(system_time());
147			break;
148		default:
149			BHandler::MessageReceived(message);
150			break;
151	}
152}
153
154
155