1/*
2 * Copyright 2002, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _DORMANT_NODE_MANAGER_H
6#define _DORMANT_NODE_MANAGER_H
7
8
9#include <map>
10
11#include <Locker.h>
12#include <MediaAddOn.h>
13
14
15class BPath;
16
17
18namespace BPrivate {
19namespace media {
20
21// To instantiate a dormant node in the current address space, we need to
22// either load the add-on from file and create a new BMediaAddOn class and
23// cache the BMediaAddOn after that for later reuse, or reuse the cached
24// BMediaAddOn if we already have one.
25// This is handled by the DormantNodeManager.
26//
27// GetAddon() will provide a ready to use BMediaAddOn, while
28// PutAddonDelayed() will unload it when it's no longer needed,
29// but will delay the unloading slightly, because it is called
30// from a node destructor of the loaded add-on.
31
32class DormantNodeManager {
33public:
34								DormantNodeManager();
35								~DormantNodeManager();
36
37	// Be careful, GetAddon and PutAddon[Delayed] must be balanced.
38			BMediaAddOn*		GetAddOn(media_addon_id id);
39			void				PutAddOn(media_addon_id id);
40			void				PutAddOnDelayed(media_addon_id id);
41
42	// For use by media_addon_server only
43			media_addon_id		RegisterAddOn(const char* path);
44			void				UnregisterAddOn(media_addon_id id);
45
46	// query the server for the path
47			status_t			FindAddOnPath(BPath* path, media_addon_id id);
48
49private:
50			struct loaded_add_on_info {
51				BMediaAddOn*	add_on;
52				image_id		image;
53				int32			use_count;
54			};
55
56	// returns the addon or NULL if it needs to be loaded
57			BMediaAddOn*		_LookupAddOn(media_addon_id id);
58
59	// manage loading and unloading add-ons from images
60			status_t			_LoadAddOn(const char* path, media_addon_id id,
61									BMediaAddOn** _newAddOn,
62									image_id* _newImage);
63			void				_UnloadAddOn(BMediaAddOn* addOn,
64									image_id image);
65
66private:
67			typedef std::map<media_addon_id, loaded_add_on_info> AddOnMap;
68
69			BLocker				fLock;
70			AddOnMap			fAddOnMap;
71};
72
73
74extern DormantNodeManager* gDormantNodeManager;
75
76
77}	// namespace media
78}	// namespace BPrivate
79
80
81using BPrivate::media::gDormantNodeManager;
82
83
84#endif /* _DORMANT_NODE_MANAGER_H */
85