summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/pluginloader.h
blob: 87f01db3fad817a544887660add2165fc2e3c04c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/***************************************************************************
                          pluginloader.h
                             -------------------
    begin                : Mon Jan 13 2003
    copyright            : (C) 2003 by Andrew Sutton
    email                : ansutton@kent.edu
  Bugs and comments to uml-devel@lists.sf.net or http://bugs.trinitydesktop.org
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef UMBRELLO_PLUGINLOADER_H
#define UMBRELLO_PLUGINLOADER_H

// TQt includes
#include <tqobject.h>
#include <tqvaluelist.h>
#include <tqmap.h>

// forward declarations
class TQString;

namespace Umbrello
{
// forward declarations
class Plugin;

/**
 * @ingroup U2_Lib
 *
 * The plugin loader is an abstraction that sits on top of KLibLoader.
 * Whereas plugins are specialized shared objects, the plugin must
 * specialize the loading of those objects. Essentially, the plugin
 * loader provides a single unit of functionality - loading plugins.
 * In order to load a plugin, we must first load a shared library
 * and then use the libraries factory to create the plugin. However,
 * because a plugin is required to be a singleton, we must ensure
 * that no plugin is ever created more than once. To that end, the
 * loader must also retain a map of loaded plugins. When a loaded
 * plugin is requested, we can increase its reference count.
 *
 * On the subject of unloading, we actually have very little to do.
 * The unload method on a plugin is simply a reference decrementer.
 * When it reaches 0, the object destroys itself. Being a TQObject,
 * it will emit the destroyed signal just before deletion, allowing
 * the plugin loader to respond to the event and remove the plugin
 * from its mapping.
 *
 * The PluginLoader also manages categories of plugins. The runtime
 * categories actually reflect the directory structure of the build
 * environment with each category represented by the name of a
 * directory. The categories are "pre-seeded" at startup.
 *
 * @bug Plugins are not removed from their respective categories
 * when they are destroyed. It may be acceptable to call
 * Plugin::category() from slotDestroyed because the category()
 * method doesn't reference any local variables - it just returns
 * a string.
 */
class PluginLoader : public TQObject
{
    Q_OBJECT
  
public:
    /** Destry the plugin loader */
    ~PluginLoader();


    /** Just a container of plugins */
    typedef TQValueList<Plugin *> PluginList;

    /** The containment type for mapping plugins */
    typedef TQMap<TQString, Plugin *> PluginMap;

    /** Container of plugin categories */
    typedef TQMap<TQString, PluginList> CategoryMap;

    /** Singleton accessor */
    static PluginLoader *instance();

    /**
     * Load a plugin. Test to see if the plugin already exists. If it
     * does, just add a reference to it and continue on.
     */
    Plugin *loadPlugin(const TQString &name);

    /** Find a plugin */
    Plugin *findPlugin(const TQString &name);

    /**
     * Unload a plugin. Never use this method. It is only used by the deref
     * method of a plugin to cause this class to unload the corresponding
     * library. In fact, there is actually no corresponding plugin to unload,
     * we just unload the library.
     */
    void unloadPlugin(const TQString &name);

    /**
     * Get a reference to the plugin mapping. This method wraps everything
     * in consts with the express purpose that no changes are made to the
     * plugin map after using this method.
     */
    const PluginMap &plugins() const;

    /** Get a reference to the plugin category mapping. */
    const CategoryMap &categories() const;

private slots:
    /**
     * This is used to connect to the destroyed signal emitted by plugins
     * when they are finally deleted. The plugin loader uses this signal
     * to remove the plugin from the plugin map.
     */
    void slotDestroyed(TQObject *obj);

private:
    /** Private constructor - This must be created through the instance method */
    PluginLoader();

    static PluginLoader        *_instance;      ///< Singleton instance
    PluginMap                   _plugins;       ///< The plugin mapping
    CategoryMap                 _categories;    ///< Categories of plugins
};
}

#endif