1818b3094aeb93b26f382365601406c51c698da4
[gregoa/zavai.git] / src / registry.vala
1 /* 
2  * registry - zavai resource registry
3  *
4  * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 using GLib;
22 using Gee;
23
24 namespace zavai {
25
26 public interface Resource : Object {
27         /**
28          * Shut down this resource.
29          *
30          * Normally one does nothing here, but it is important to give resources a
31          * chance to do cleanup when the program quits.
32          * 
33          * This can be used for tasks like closing the tags on a GPX track,
34          * releasing a FSO resource, restoring mixer settings and so on.
35          */
36         public abstract void shutdown();
37 }
38
39 public abstract class Service : Object, Resource {
40         public string name { get; construct; }
41
42         bool _started;
43         public bool started {
44                 get { return _started; }
45                 set { _started = value; }
46                 default = false;
47         }
48
49         public signal void toggled(bool new_state);
50
51         protected HashMap<string, int> requests;
52
53         construct {
54                 requests = new HashMap<string, int>(str_hash, str_equal);
55         }
56
57         public void shutdown()
58         {
59                 stop();
60         }
61
62         /// Activate the service
63         protected virtual void start()
64         {
65                 if (!started)
66                 {
67 stderr.printf("SERVICE %s started\n", name);
68                         started = true;
69                         toggled(started);
70                 }
71         }
72
73         /// Deactivate the service
74         protected virtual void stop()
75         {
76                 if (started)
77                 {
78 stderr.printf("SERVICE %s stopped\n", name);
79                         started = false;
80                         toggled(started);
81                 }
82         }
83
84         /**
85           Request a resource using the given ID.
86          *
87          * If it is the first time the resource is requested, start it and
88          * return true. Else, take note of the request and return false.
89          *
90          * If a resource is requested multiple times with the same ID, it will
91          * need to be released multiple times with that ID.
92          */
93         public bool request(string id)
94         {
95                 bool res = (requests.size == 0);
96                 if (id in requests)
97                         requests[id] = requests[id] + 1;
98                 else
99                         requests.set(id, 1);
100                 if (res) start();
101                 return res;
102         }
103
104         /**
105          * Release a resource using the given ID.
106          *
107          * If after the call nothing is requesting the resource, stop it and
108          * return true. Else, take note of the release and return false.
109          *
110          * If a resource is requested multiple times with the same ID, it will
111          * need to be released multiple times with that ID.
112          */
113         public bool release(string id)
114         {
115                 if (id in requests)
116                 {
117                         if (requests[id] > 1)
118                                 requests[id] = requests[id] - 1;
119                         else
120                                 requests.remove(id);
121                 } else {
122                         return false;
123                 }
124                 if (requests.size > 0)
125                         return false;
126                 stop();
127                 return true;
128         }
129 }
130
131 public class Registry : Object, Resource
132 {
133         HashMap<string, Resource> memb_resources;
134         HashMap<string, Service> memb_services;
135         HashMap<string, Applet> memb_applets;
136         HashMap<string, Menu> memb_menus;
137         protected ArrayList<Resource> registration_order;
138         public DBus.Connection sbus;
139     public string bus_name;
140
141         public Registry()
142         {
143                 memb_resources = new HashMap<string, Resource>(str_hash, str_equal);
144                 memb_services = new HashMap<string, Service>(str_hash, str_equal);
145                 memb_applets = new HashMap<string, Applet>(str_hash, str_equal);
146                 memb_menus = new HashMap<string, Menu>(str_hash, str_equal);
147                 registration_order = new ArrayList<Resource>();
148                 sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
149
150         bus_name = DBus.bus_get_unique_name(sbus.get_connection());
151         zavai.log.info("My bus name: " + bus_name);
152
153 stderr.printf("ZA1\n");
154         dynamic DBus.Object tmp_dbus = sbus.get_object(
155             "org.freedesktop.DBus",
156             "/org/freedesktop/DBus",
157             "org.freedesktop.DBus");
158 stderr.printf("ZA2\n");
159         bus_name = "org.enricozini.zavai";
160         uint res = tmp_dbus.RequestName(bus_name, (uint)DBus.NameFlag.DO_NOT_QUEUE);
161         stderr.printf("RN: %u\n", res);
162         switch (res)
163         {
164             case DBus.RequestNameReply.PRIMARY_OWNER:
165                 zavai.log.info("Registered to dbus as " + bus_name);
166                 break;
167             case DBus.RequestNameReply.IN_QUEUE:
168                 zavai.log.info("In queue, but I asked not to");
169                 break;
170             case DBus.RequestNameReply.EXISTS:
171                 zavai.log.info(bus_name + " already exists");
172                 break;
173             case DBus.RequestNameReply.ALREADY_OWNER:
174                 zavai.log.info("I already own the name " + bus_name + " but I do not remember asking for it");
175                 break;
176         }
177 stderr.printf("ZA3\n");
178         }
179
180         public void shutdown()
181         {
182                 // Shutdown in reverse registration order
183                 for (int i = registration_order.size - 1; i >= 0; --i) 
184                         registration_order[i].shutdown();
185         }
186
187         public void register_resource(string name, Resource obj)
188         {
189                 memb_resources[name] = obj;
190                 registration_order.add(obj);
191         }
192
193         public void register_service(Service obj)
194         {
195                 memb_services[obj.name] = obj;
196                 registration_order.add(obj);
197         }
198
199         public void register_applet(string name, Applet obj)
200         {
201                 memb_applets[name] = obj;
202                 registration_order.add(obj);
203         }
204
205         public void register_menu(string name, Menu obj)
206         {
207                 memb_applets[name] = obj;
208                 memb_menus[name] = obj;
209                 registration_order.add(obj);
210         }
211
212         public Resource? getr(string name)
213         {
214                 if (name in memb_resources)
215                         return memb_resources[name];
216                 else
217                 {
218                         log.error("getr: no resource found: " + name);
219                         return null;
220                 }
221         }
222
223         public Service? gets(string name)
224         {
225                 if (name in memb_services)
226                         return memb_services[name];
227                 else
228                 {
229                         log.error("gets: no service found: " + name);
230                         return null;
231                 }
232         }
233
234         public Applet? geta(string name)
235         {
236                 if (name in memb_applets)
237                         return memb_applets[name];
238                 else
239                 {
240                         log.error("geta: no applet found: " + name);
241                         return null;
242                 }
243         }
244
245         public Menu? getmenu(string name)
246         {
247                 if (name in memb_menus)
248                         return memb_menus[name];
249                 else
250                 {
251                         log.error("getmenu: no menu found: " + name);
252                         return null;
253                 }
254         }
255 }
256
257 zavai.Registry registry;
258
259 }
260