*/
using GLib;
-using Gee;
namespace zavai {
-public interface Resource : Object {
- /**
- * Shut down this resource.
- *
- * Normally one does nothing here, but it is important to give resources a
- * chance to do cleanup when the program quits.
- *
- * This can be used for tasks like closing the tags on a GPX track,
- * releasing a FSO resource, restoring mixer settings and so on.
- */
- public abstract void shutdown();
-}
-
-public abstract class Service : Object, Resource {
- public string name { get; construct; }
-
- bool _started;
- public bool started {
- get { return _started; }
- set { _started = value; }
- default = false;
- }
-
- public signal void toggled(bool new_state);
-
- protected HashMap<string, int> requests;
-
- construct {
- requests = new HashMap<string, int>(str_hash, str_equal);
- }
-
- public void shutdown()
- {
- stop();
- }
-
- /// Activate the service
- protected virtual void start()
- {
- if (!started)
- {
-stderr.printf("SERVICE %s started\n", name);
- started = true;
- toggled(started);
- }
- }
-
- /// Deactivate the service
- protected virtual void stop()
- {
- if (started)
- {
-stderr.printf("SERVICE %s stopped\n", name);
- started = false;
- toggled(started);
- }
- }
-
- /**
- Request a resource using the given ID.
- *
- * If it is the first time the resource is requested, start it and
- * return true. Else, take note of the request and return false.
- *
- * If a resource is requested multiple times with the same ID, it will
- * need to be released multiple times with that ID.
- */
- public bool request(string id)
- {
- bool res = (requests.size == 0);
- if (id in requests)
- requests[id] = requests[id] + 1;
- else
- requests.set(id, 1);
- if (res) start();
- return res;
- }
-
- /**
- * Release a resource using the given ID.
- *
- * If after the call nothing is requesting the resource, stop it and
- * return true. Else, take note of the release and return false.
- *
- * If a resource is requested multiple times with the same ID, it will
- * need to be released multiple times with that ID.
- */
- public bool release(string id)
- {
- if (id in requests)
- {
- if (requests[id] > 1)
- requests[id] = requests[id] - 1;
- else
- requests.remove(id);
- } else {
- return false;
- }
- if (requests.size > 0)
- return false;
- stop();
- return true;
- }
-}
-
-// class Service(Resource):
-// "Service that is activated only when someone is listening"
-// def __init__(self, types = []):
-// """
-// Initialise a service that can emit signals for the given event types
-// """
-// super(Service, self).__init__()
-// self.callbacks = dict()
-// for t in types:
-// self.callbacks[t] = set()
-// self.started = False
-//
-// def notify(self, type, *args, **kw):
-// "Call all callbacks with the given parameters"
-// for cb in self.callbacks[type]:
-// cb(*args, **kw)
-//
-// def has_callbacks(self):
-// for i in self.callbacks.values():
-// if i: return True
-// return False
-//
-// def connect(self, type, callback):
-// "Connect a callback to this resource, activating it if needed"
-// do_start = not self.has_callbacks()
-// self.callbacks[type].add(callback)
-// if do_start:
-// self.start()
-// self.started = True
-//
-// def disconnect(self, type, callback):
-// "Disconnect a callback to this resource, activating it if needed"
-// if not self.has_callbacks(): return
-// self.callbacks[type].discard(callback)
-// if not self.has_callbacks():
-// self.stop()
-// self.started = False
-
-
-// import zavai
-// import gtk
-//
-// def get_parent(s):
-// "Get the parent name for s"
-// pos = s.rfind(".")
-// if pos == -1: return None
-// res = s[:pos]
-// if res == "menu": return None
-// return res
-//
-// def default_label(s):
-// "Compute a default label given the last element of a path"
-// pos = s.rfind(".")
-// if pos == -1: return s.capitalize()
-// return s[pos+1:].capitalize()
-
public class Registry : Object, Resource
{
- HashMap<string, Resource> memb_resources;
- HashMap<string, Service> memb_services;
- HashMap<string, Applet> memb_applets;
- HashMap<string, Menu> memb_menus;
- protected ArrayList<Resource> registration_order;
- public DBus.Connection sbus;
-
- public Registry()
- {
- memb_resources = new HashMap<string, Resource>(str_hash, str_equal);
- memb_services = new HashMap<string, Service>(str_hash, str_equal);
- memb_applets = new HashMap<string, Applet>(str_hash, str_equal);
- memb_menus = new HashMap<string, Menu>(str_hash, str_equal);
- registration_order = new ArrayList<Resource>();
- sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
- }
-
- public void shutdown()
- {
- // Shutdown in reverse registration order
- for (int i = registration_order.size - 1; i >= 0; --i)
- registration_order[i].shutdown();
- }
-
- public void register_resource(string name, Resource obj)
- {
- memb_resources[name] = obj;
- registration_order.add(obj);
- }
-
- public void register_service(Service obj)
- {
- memb_services[obj.name] = obj;
- registration_order.add(obj);
- }
-
- public void register_applet(string name, Applet obj)
- {
- memb_applets[name] = obj;
- registration_order.add(obj);
- }
-
- public void register_menu(string name, Menu obj)
- {
- memb_applets[name] = obj;
- memb_menus[name] = obj;
- registration_order.add(obj);
- }
-
- public Resource? getr(string name)
- {
- if (name in memb_resources)
- return memb_resources[name];
- else
- {
- log.error("getr: no resource found: " + name);
- return null;
- }
- }
-
- public Service? gets(string name)
- {
- if (name in memb_services)
- return memb_services[name];
- else
- {
- log.error("gets: no service found: " + name);
- return null;
- }
- }
-
- public Applet? geta(string name)
- {
- if (name in memb_applets)
- return memb_applets[name];
- else
- {
- log.error("geta: no applet found: " + name);
- return null;
- }
- }
-
- public Menu? getmenu(string name)
- {
- if (name in memb_menus)
- return memb_menus[name];
- else
- {
- log.error("getmenu: no menu found: " + name);
- return null;
- }
- }
+ List<Resource> resources;
+ public DBus.Connection sbus;
+ public string bus_name;
+
+ public Registry()
+ {
+ resources = new List<Resource>();
+ try {
+ sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
+ } catch (DBus.Error e) {
+ stderr.printf("Cannot access system DBus bus: %s\n", e.message);
+ sbus = null;
+ }
+
+ bus_name = DBus.bus_get_unique_name(sbus.get_connection());
+ zavai.log.info("My bus name: " + bus_name);
+
+ dynamic DBus.Object tmp_dbus = sbus.get_object(
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+ bus_name = "org.enricozini.zavai";
+ uint res = tmp_dbus.RequestName(bus_name, (uint)DBus.NameFlag.DO_NOT_QUEUE);
+ switch (res)
+ {
+ case DBus.RequestNameReply.PRIMARY_OWNER:
+ zavai.log.info("Registered to dbus as " + bus_name);
+ break;
+ case DBus.RequestNameReply.IN_QUEUE:
+ zavai.log.info("In queue, but I asked not to");
+ break;
+ case DBus.RequestNameReply.EXISTS:
+ zavai.log.info(bus_name + " already exists");
+ break;
+ case DBus.RequestNameReply.ALREADY_OWNER:
+ zavai.log.info("I already own the name " + bus_name + " but I do not remember asking for it");
+ break;
+ }
+ }
+
+ public void shutdown()
+ {
+ // Shutdown in reverse registration order
+ for (weak List<Resource> i = resources; i != null; i = i.next)
+ i.data.shutdown();
+ }
+
+ public void register(Resource obj)
+ {
+ resources.prepend(obj);
+ }
}
-// class Registry(object):
-// """Collection of resources.
-//
-// Various factories can be registered by name on the registry. Then when an
-// object is requested for the first time, it is created using the factory.
-// When it is requested again, the existing object is reused.
-// """
-//
-// def __init__(self):
-// self.factories = dict()
-// self.objects = dict()
-// self.labels = dict()
-//
-// def register(self, obj, name=None):
-// """Register an object at the given path.
-//
-// Name the path to this object, like "menu.gps.monitor".
-// """
-// if name is None:
-// name = obj.props.name
-//
-// if name in self.objects:
-// return KeyError("%s is already registered", name)
-// zavai.info("Registering", name)
-// self.objects[name] = obj
-//
-// if name.startswith("menu."):
-// self.add_to_menu(name)
-//
-// def register_factory(self, fac, name, label = None):
-// """Register an object factory at the given path.
-//
-// Name the path to this object, like "menu.gps.monitor".
-// """
-// if name in self.factories:
-// return KeyError("Factory %s is already registered", name)
-// zavai.info("Registering factory", name)
-// self.factories[name] = fac
-// if label is not None: self.labels[name] = label
-//
-// def add_to_menu(self, name):
-// "Add the applet with the given name to the menu structure"
-// parent = get_parent(name)
-// if parent is not None:
-// zavai.info("Add to menu", name, parent)
-// menu = self.menu(parent)
-//
-// obj = self.resource(name)
-// if isinstance(obj, gtk.ToggleAction):
-// menu.add_child(zavai.ToggleButton(self, name, action=obj))
-// elif isinstance(obj, gtk.Action):
-// menu.add_child(zavai.LinkButton(self, name, action=obj))
-// else:
-// menu.add_child(zavai.LinkButton(self, name, self.label(name)))
-//
-// def label(self, name):
-// "Return the label for the object with the given name"
-// res = self.labels.get(name)
-// if res is not None:
-// return res
-// try:
-// obj = self.resource(name)
-// return obj.props.label
-// except:
-// return default_label(name)
-//
-// def resource(self, name):
-// """Get a resource from the registry.
-//
-// If no resource exists at `name` but there is a factory, instantiate the
-// object using the factory.
-//
-// If not even a factory exists at `name`, returns None.
-// """
-// res = self.objects.get(name, None)
-// if res is None:
-// fac = self.factories.get(name, None)
-// if fac is not None:
-// res = self.objects[name] = fac(self, name)
-// return res
-//
-// def menu(self, name):
-// """Get a menu resource, automatically creating it if it is missing.
-//
-// Menus are created automatically linked to a parent menu, according to
-// the hierarchy in `name`.
-// """
-// res = self.resource(name)
-// if res is None:
-// # Check if it is a toplevel menu
-// if name.startswith("menu."):
-// parent = get_parent(name[5:])
-// if parent is not None:
-// parent = "menu." + parent
-// else:
-// parent = get_parent(name)
-//
-// res = zavai.Menu(self, name, parent)
-// self.register(res, name)
-// return res
-//
-// def shutdown(self):
-// """Shut down all objects in this Registry.
-//
-// After shutting down, all objects cannot be used anymore"""
-// for o in self.objects.itervalues():
-// if isinstance(o, Resource):
-// o.shutdown()
-// self.objects.clear()
-//
-
-zavai.Registry registry;
+public zavai.Registry registry;
}