1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1995-1997 Presto Studios, Inc.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 *
24 */
25
26 #include "pegasus/constants.h"
27 #include "pegasus/notification.h"
28
29 namespace Pegasus {
30
31 typedef ReceiverList::iterator ReceiverIterator;
32
Notification(const NotificationID id,NotificationManager * owner)33 Notification::Notification(const NotificationID id, NotificationManager *owner) : IDObject(id) {
34 _owner = owner;
35 _currentFlags = kNoNotificationFlags;
36 if (_owner)
37 _owner->addNotification(this);
38 }
39
~Notification()40 Notification::~Notification() {
41 for (uint i = 0; i < _receivers.size(); i++)
42 _receivers[i].receiver->newNotification(NULL);
43
44 if (_owner)
45 _owner->removeNotification(this);
46 }
47
48 // Selectively set or clear notificiation bits.
49 // Wherever mask is 0, leave existing bits untouched.
50 // Wherever mask is 1, set bit equivalent to flags.
notifyMe(NotificationReceiver * receiver,NotificationFlags flags,NotificationFlags mask)51 void Notification::notifyMe(NotificationReceiver *receiver, NotificationFlags flags, NotificationFlags mask) {
52 for (uint i = 0; i < _receivers.size(); i++) {
53 if (_receivers[i].receiver == receiver) {
54 _receivers[i].mask = (_receivers[i].mask & ~mask) | (flags & mask);
55 receiver->newNotification(this);
56 return;
57 }
58 }
59
60 ReceiverEntry newEntry;
61 newEntry.receiver = receiver;
62 newEntry.mask = flags;
63 _receivers.push_back(newEntry);
64
65 receiver->newNotification(this);
66 }
67
cancelNotification(NotificationReceiver * receiver)68 void Notification::cancelNotification(NotificationReceiver *receiver) {
69 for (uint i = 0; i < _receivers.size(); i++) {
70 if (_receivers[i].receiver == receiver) {
71 _receivers.remove_at(i);
72 i--;
73 }
74 }
75 }
76
setNotificationFlags(NotificationFlags flags,NotificationFlags mask)77 void Notification::setNotificationFlags(NotificationFlags flags, NotificationFlags mask) {
78 _currentFlags = (_currentFlags & ~mask) | flags;
79 }
80
checkReceivers()81 void Notification::checkReceivers() {
82 NotificationFlags currentFlags = _currentFlags;
83 _currentFlags = kNoNotificationFlags;
84
85 for (uint i = 0; i < _receivers.size(); i++)
86 if (_receivers[i].mask & currentFlags)
87 _receivers[i].receiver->receiveNotification(this, currentFlags);
88 }
89
90 // Receiver entries are equal if their receivers are equal.
91
operator ==(const ReceiverEntry & entry1,const ReceiverEntry & entry2)92 int operator==(const ReceiverEntry &entry1, const ReceiverEntry &entry2) {
93 return entry1.receiver == entry2.receiver;
94 }
95
operator !=(const ReceiverEntry & entry1,const ReceiverEntry & entry2)96 int operator!=(const ReceiverEntry &entry1, const ReceiverEntry &entry2) {
97 return entry1.receiver != entry2.receiver;
98 }
99
NotificationReceiver()100 NotificationReceiver::NotificationReceiver() {
101 _notification = NULL;
102 }
103
~NotificationReceiver()104 NotificationReceiver::~NotificationReceiver() {
105 if (_notification)
106 _notification->cancelNotification(this);
107 }
108
receiveNotification(Notification *,const NotificationFlags)109 void NotificationReceiver::receiveNotification(Notification *, const NotificationFlags) {
110 }
111
newNotification(Notification * notification)112 void NotificationReceiver::newNotification(Notification *notification) {
113 _notification = notification;
114 }
115
116 typedef NotificationList::iterator NotificationIterator;
117
NotificationManager()118 NotificationManager::NotificationManager() {
119 }
120
~NotificationManager()121 NotificationManager::~NotificationManager() {
122 detachNotifications();
123 }
124
addNotification(Notification * notification)125 void NotificationManager::addNotification(Notification *notification) {
126 _notifications.push_back(notification);
127 }
128
removeNotification(Notification * notification)129 void NotificationManager::removeNotification(Notification *notification) {
130 for (NotificationIterator it = _notifications.begin(); it != _notifications.end();) {
131 if ((*it) == notification)
132 it = _notifications.erase(it);
133 else
134 it++;
135 }
136 }
137
detachNotifications()138 void NotificationManager::detachNotifications() {
139 for (NotificationIterator it = _notifications.begin(); it != _notifications.end(); it++)
140 (*it)->_owner = 0;
141 }
142
checkNotifications()143 void NotificationManager::checkNotifications() {
144 for (NotificationIterator it = _notifications.begin(); it != _notifications.end(); it++)
145 if ((*it)->_currentFlags != kNoNotificationFlags)
146 (*it)->checkReceivers();
147 }
148
149 } // End of namespace Pegasus
150