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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53 - (hide 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 schoenebeck 53 /***************************************************************************
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