summaryrefslogtreecommitdiff
path: root/plugins/dbus/dbussignaller.hpp
blob: 2f6fcc49a604cc6995f078c106fbcd764e9012a4 (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
#ifndef _DBUSSIGNALLER_H_
#define _DBUSSINGALLER_H_

#include <gio/gio.h>
#include <map>
#include <string>

#include "debugout.h"
#include "abstractproperty.h"

class DBusSignaller
{
public:

	static DBusSignaller* factory(int timeout)
	{
		return new DBusSignaller(timeout);
	}

	void fireSignal(GDBusConnection* conn, std::string objPath, std::string iface, std::string sigName, AbstractProperty* prop)
	{
		DBusSignal signal(conn, objPath, iface, sigName, prop);

		queue[objPath] = signal;
	}

	class DBusSignal
	{
	public:
		DBusSignal():connection(nullptr), property(nullptr){}
		DBusSignal(GDBusConnection* conn, std::string objPath, std::string iface, std::string sigName, AbstractProperty* var)
			: connection(conn), objectPath(objPath), interface(iface), signalName(sigName), property(var)
		{

		}

		GDBusConnection* connection;
		std::string objectPath;
		std::string interface;
		std::string signalName;
		AbstractProperty* property;
	};

private:

	DBusSignaller() { }

	DBusSignaller(int timeout)
	{
		g_timeout_add(timeout,[](gpointer userData)
		{
			std::map<std::string, DBusSignal> *q = static_cast<std::map<std::string, DBusSignal>*>(userData);
			std::map<std::string, DBusSignal> queue = *q;

			for(auto sig : queue)
			{
				DBusSignal signal = sig.second;

				GError* error = nullptr;

				AbstractProperty* property = signal.property;

				GVariant* val = g_variant_ref(property->toGVariant());

				/// Send PropertiesChanged signal

				GVariantBuilder builder;
				g_variant_builder_init(&builder, G_VARIANT_TYPE_DICTIONARY);

				g_variant_builder_add(&builder, "{sv}", property->name().c_str(), val);
				g_variant_builder_add(&builder, "{sv}", std::string(property->name() + "Sequence").c_str(), g_variant_new("i", property->sequence()));
				g_variant_builder_add(&builder, "{sv}", "Time", g_variant_new("d", property->timestamp()) );

				g_dbus_connection_emit_signal(signal.connection, NULL, signal.objectPath.c_str(), signal.interface.c_str(), signal.signalName.c_str(), g_variant_new("(sa{sv}as)",
																																									 signal.interface.c_str(),
																																									 &builder, NULL), &error);

				if(error)
				{
					DebugOut(DebugOut::Error)<<error->message<<std::endl;
				}

				queue.erase(signal.objectPath);

			}

			*q = queue;

			return 1;

		},&queue);
	}

	std::map<std::string, DBusSignal> queue;


};

#endif