/[svn]/linuxsampler/trunk/src/common/ResourceManager.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/common/ResourceManager.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53 - (show annotations) (download) (as text)
Mon Apr 26 17:15:51 2004 UTC (19 years, 11 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 11013 byte(s)
* completely restructured source tree
* implemented multi channel support
* implemented instrument manager, which controls sharing of instruments
  between multiple sampler engines / sampler channels
* created abstract classes 'AudioOutputDevice' and 'MidiInputDevice' for
  convenient implementation of further audio output driver and MIDI input
  driver for LinuxSampler
* implemented following LSCP commands: 'SET CHANNEL MIDI INPUT TYPE',
  'LOAD ENGINE', 'GET CHANNELS', 'ADD CHANNEL', 'REMOVE CHANNEL',
  'SET CHANNEL AUDIO OUTPUT TYPE'
* temporarily removed all command line options
* LSCP server is now launched by default

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #ifndef __RESOURCE_MANAGER__
24 #define __RESOURCE_MANAGER__
25
26 #include <set>
27 #include <map>
28
29 /**
30 * Interface class for consumer classes which use a resource managed
31 * by the ResourceManager class.
32 */
33 template<class T_res>
34 class ResourceConsumer {
35 public:
36 /**
37 * Will be called by the ResourceManager to inform the
38 * consumer that a resource currently used by him is going
39 * to be updated. The consumer can then react by stopping
40 * usage until resource is updated. The ResourceManager will
41 * not update the resource until this method returns. This
42 * method needs to be implemented by the consumer.
43 *
44 * @param pResource - resource going to be updated
45 * @param pUpdateArg - pointer the consumer might use to store
46 * informations he might need when update
47 * process was completed
48 */
49 virtual void ResourceToBeUpdated(T_res* pResource, void*& pUpdateArg) = 0;
50
51 /**
52 * Will be called by the ResourceManager to inform the
53 * consumer that resource update was completed. This method
54 * needs to be implemented by the consumer.
55 *
56 * @param pOldResource - (now invalid) pointer to the old
57 * resource
58 * @param pNewResource - (valid) pointer to the updated
59 * resource
60 * @param pUpdateArg - pointer the consumer might have used when
61 * ResourceToBeUpdated() was called
62 */
63 virtual void ResourceUpdated(T_res* pOldResource, T_res* pNewResource, void* pUpdateArg) = 0;
64 };
65
66 /**
67 * Abstract base class for sharing resources between multiple consumers.
68 * A consumer can borrow a resource from the ResourceManager, if the
69 * resource doesn't exist yet it will be created. Other consumers will
70 * just be given the same pointer to the resource then. When all consumers
71 * gave back their pointer to the resource, the resource will be destroyed.
72 * Descendants of this base class have to implement the (protected)
73 * Create() and Destroy() methods to create and destroy a resource.
74 */
75 template<class T_key, class T_res>
76 class ResourceManager {
77 private:
78 typedef std::set<ResourceConsumer<T_res>*> ConsumerSet;
79 struct resource_entry_t {
80 T_key key;
81 T_res* resource; ///< pointer to the resource
82 ConsumerSet consumers; ///< list of all consumers who currently use the resource
83 void* arg; ///< optional pointer the descendant might use to store informations about the resource
84 };
85 typedef std::map<T_key, resource_entry_t> ResourceMap;
86 ResourceMap ResourceEntries;
87
88 public:
89 /**
90 * Borrow a resource identified by \a Key. The ResourceManager will
91 * mark the resource as in usage by the consumer given with
92 * \a pConsumer. If the Resource doesn't exist yet it will be
93 * created.
94 *
95 * @param Key - resource identifier
96 * @param pConsumer - identifier of the consumer who borrows it
97 * @returns pointer to resource
98 */
99 T_res* Borrow(T_key Key, ResourceConsumer<T_res>* pConsumer) {
100 typename ResourceMap::iterator iterEntry = ResourceEntries.find(Key);
101 if (iterEntry == ResourceEntries.end()) {
102 resource_entry_t entry;
103 entry.key = Key;
104 entry.resource = Create(Key, pConsumer, entry.arg);
105 entry.consumers.insert(pConsumer);
106 OnBorrow(entry.resource, pConsumer, entry.arg);
107 ResourceEntries[Key] = entry;
108 return entry.resource;
109 }
110 resource_entry_t& entry = iterEntry->second;
111 entry.consumers.insert(pConsumer);
112 OnBorrow(entry.resource, pConsumer, entry.arg);
113 return entry.resource;
114 }
115
116 /**
117 * Give back a resource. This tells the ResourceManager that the
118 * consumer given by \a pConsumer doesn't need the resource anymore.
119 * If the resource is not needed by any consumer anymore then the
120 * resource will be destroyed.
121 *
122 * @param pResource - pointer to resource
123 * @param pConsumer - identifier of the consumer who borrowed the
124 * resource
125 */
126 void HandBack(T_res* pResource, ResourceConsumer<T_res>* pConsumer) {
127 typename ResourceMap::iterator iter = ResourceEntries.begin();
128 typename ResourceMap::iterator end = ResourceEntries.end();
129 for (; iter != end; iter++) {
130 if (iter->second.resource = pResource) {
131 resource_entry_t& entry = iter->second;
132 entry.consumers.erase(pConsumer);
133 if (entry.consumers.empty()) {
134 ResourceEntries.erase(iter);
135 Destroy(entry.resource, entry.arg);
136 }
137 return;
138 }
139 }
140 }
141
142 /**
143 * Request update of a resource.
144 *
145 * @param pResource - resource to be updated
146 * @param pConsumer - consumer who requested the update
147 */
148 void Update(T_res* pResource, ResourceConsumer<T_res>* pConsumer) {
149 typename ResourceMap::iterator iter = ResourceEntries.begin();
150 typename ResourceMap::iterator end = ResourceEntries.end();
151 for (; iter != end; iter++) {
152 if (iter->second.resource = pResource) {
153 resource_entry_t& entry = iter->second;
154 // inform all consumers about pending update
155 std::map<ResourceConsumer<T_res>*,void*> updateargs;
156 typename ConsumerSet::iterator iterCons = entry.consumers.begin();
157 typename ConsumerSet::iterator endCons = entry.consumers.end();
158 for (; iterCons != endCons; iterCons++) {
159 if (*iterCons == pConsumer) continue;
160 void* updatearg = NULL;
161 (*iterCons)->ResourceToBeUpdated(entry.resource, updatearg);
162 if (updatearg) updateargs[*iterCons] = updatearg;
163 }
164 // update resource
165 T_res* pOldResource = entry.resource;
166 Destroy(entry.resource, entry.arg);
167 entry.resource = Create(entry.key, pConsumer, entry.arg);
168 // inform all consumers about update completed
169 iterCons = entry.consumers.begin();
170 endCons = entry.consumers.end();
171 for (; iterCons != endCons; iterCons++) {
172 if (*iterCons == pConsumer) continue;
173 typename std::map<ResourceConsumer<T_res>*,void*>::iterator iterArg = updateargs.find(*iterCons);
174 void* updatearg = (iterArg != updateargs.end()) ? iterArg->second : NULL;
175 (*iterCons)->ResourceUpdated(pOldResource, entry.resource, updatearg);
176 }
177 return;
178 }
179 }
180 }
181
182 protected:
183 /**
184 * Has to be implemented by the descendant to create (allocate) a
185 * resource identified by \a Key.
186 *
187 * @param Key - identifier of the resource
188 * @param pConsumer - identifier of the consumer who borrows the
189 * resource
190 * @param pArg - pointer the descendant can use to store
191 * informations he might need for destruction of
192 * the resource
193 * @returns pointer to new resource
194 */
195 virtual T_res* Create(T_key Key, ResourceConsumer<T_res>* pConsumer, void*& pArg) = 0;
196
197 /**
198 * Has to be implemented by the descendant to destroy (free) a
199 * resource pointed by \a pResource.
200 *
201 * @param pResource - pointer to the resource
202 * @param pArg - pointer the descendant might have used when
203 * Create() was called to store informations
204 * about the resource
205 */
206 virtual void Destroy(T_res* pResource, void* pArg) = 0;
207
208 /**
209 * Has to be implemented by the descendant to react when a consumer
210 * borrows a resource (no matter if freshly created or an already
211 * created one). Of course reacting is optional, but the descendant
212 * at least has to provide a method with empty body.
213 *
214 * @param pResource - pointer to the resource
215 * @param pConsumer - identifier of the consumer who borrows the
216 * resource
217 * @param pArg - pointer the descendant might have used when
218 * Create() was called to store informations
219 * about the resource, this information can be
220 * updated by the descendant here
221 */
222 virtual void OnBorrow(T_res* pResource, ResourceConsumer<T_res>* pConsumer, void*& pArg) = 0;
223 };
224
225 #endif // __RESOURCE_MANAGER__

  ViewVC Help
Powered by ViewVC