1 /* SettingNotifier.h */
2 
3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4  *
5  * This file is part of sayonara player
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef SETTINGNOTIFIER_H
22 #define SETTINGNOTIFIER_H
23 
24 #include <functional>
25 #include <QObject>
26 
27 #pragma once
28 
29 class AbstrSettingNotifier : public QObject
30 {
31 	Q_OBJECT
32 
33 signals:
34 	void sigValueChanged();
35 
36 public:
37 	template<typename T>
38 	void addListener(T* c, void (T::*fn)())
39 	{
40 		connect(this, &AbstrSettingNotifier::sigValueChanged, c, fn);
41 	}
42 
43 	void emit_value_changed();
44 };
45 
46 template<typename KeyClass>
47 class SettingNotifier
48 {
49 private:
50 	AbstrSettingNotifier* m=nullptr;
51 
52 	SettingNotifier() :
53 		m(new AbstrSettingNotifier())
54 	{}
55 
56 	SettingNotifier(const SettingNotifier& other) = delete;
57 
58 public:
59 	~SettingNotifier() = default;
60 
61 	static SettingNotifier<KeyClass>* instance()
62 	{
63 		static SettingNotifier<KeyClass> inst;
64 		return &inst;
65 	}
66 
67 	void valueChanged()
68 	{
69 		m->emit_value_changed();
70 	}
71 
72 	template<typename T>
73 	void addListener(T* c, void (T::*fn)())
74 	{
75 		m->addListener(c, fn);
76 	}
77 };
78 
79 
80 namespace Set
81 {
82 	template<typename KeyClassInstance, typename T>
83 	//typename std::enable_if<std::is_base_of<SayonaraClass, T>::value, void>::type
84 	void
85 	listen(T* t, void (T::*fn)(), bool run=true)
86 	{
87 		SettingNotifier<KeyClassInstance>::instance()->addListener(t, fn);
88 
89 		if(run)
90 		{
91 			auto callable = std::bind(fn, t);
92 			callable();
93 		}
94 	}
95 
96 	template<typename KeyClassInstance>
97 	void shout()
98 	{
99 		SettingNotifier<KeyClassInstance>::instance()->valueChanged();
100 	}
101 }
102 
103 
104 #endif // SETTINGNOTIFIER_H
105