Skip to content

Commit f75445e

Browse files
authored
Merge pull request #48 from PedalPi/issue-45-plugins-manager-v0.5.0
Issue 45 plugins manager v0.5.0
2 parents a22283c + 41732d0 commit f75445e

27 files changed

+612
-1622
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ python:
1010
sudo: required
1111

1212
install:
13+
- sudo apt-get install -y portaudio19-dev python-all-dev --no-install-recommends
1314
- sudo apt-get install -y lilv-utils calf-plugins guitarix --no-install-recommends
1415
- pip3 install coveralls
1516

CHANGES

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
Version 0.3.0 - released 05//17
1+
Version 0.3.0 - released 05/30/17
22
=================================
33
- Issue #29 - Secure components close
44
- Issue #30 - Replace print log to logging
5-
- **Breaking change**: Issue #39 - Change save method to pluginsmanager (v0.5.0) Autosaver
5+
- **Breaking change**: Issues #39 and #5 - Change save method to pluginsmanager (v0.5.0) Autosaver
66
- Removed BanksDao -> Using now pluginsmanager Autosaver
77
- Removed Database -> Using now pluginsmanager Persistence
88
- BanksController, PedalboardController, EffectController, ParamController,
99
CurrentController changes your API
10+
- Issue #41 - Allows current pedalboard is None
11+
- Issue #40 - If current pedalboard index file is wrong, Application now starts
12+
with the current pedalboard = None
13+
- Issue #11 - Banks with same name not will be replaced when Application initialize
14+
- Issue #17 - Fixes: Remove bank with current pedalboard will be crash (when reload Application)
15+
- Issue #45 - Add plugins manager v0.5.0 support
16+
17+
- Removed BanksController, PedalboardController, EffectController, ParamController, NotificationController
18+
- Implemented :meth:`.Application.register_observer`, :meth:`.Application.unregister_observer`
19+
1020

1121
Version 0.2.1 - released 04/14/17
1222
=================================

application/application.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,14 @@
2020
from shutil import copytree
2121
from unittest.mock import MagicMock
2222

23-
from application.controller.banks_controller import BanksController
23+
from application.component.components_observer import ComponentsObserver
24+
from application.component.current_pedalboard_observer import CurrentPedalboardObserver
2425
from application.controller.component_data_controller import ComponentDataController
2526
from application.controller.current_controller import CurrentController
2627
from application.controller.device_controller import DeviceController
27-
from application.controller.effect_controller import EffectController
28-
from application.controller.notification_controller import NotificationController
29-
from application.controller.param_controller import ParamController
30-
from application.controller.pedalboard_controller import PedalboardController
3128
from application.controller.plugins_controller import PluginsController
32-
33-
from pluginsmanager.mod_host.mod_host import ModHost
3429
from pluginsmanager.observer.autosaver.autosaver import Autosaver
30+
from pluginsmanager.observer.mod_host.mod_host import ModHost
3531

3632
logging.basicConfig(format='[%(asctime)s] %(levelname)s - %(message)s', stream=sys.stdout, level=logging.DEBUG)
3733

@@ -47,7 +43,7 @@ class Application(object):
4743
for control::
4844
4945
>>> from application.application import Application
50-
>>> from application.controller.CurrentController import CurrentController
46+
>>> from application.controller.current_controller import CurrentController
5147
5248
>>> application = Application()
5349
>>> current_controller = application.controller(CurrentController)
@@ -69,16 +65,27 @@ class Application(object):
6965
"""
7066

7167
def __init__(self, path_data="data/", address="localhost", test=False):
72-
path_data = Path(path_data)
7368
self.mod_host = self._initialize(address, test)
7469

70+
# Data
71+
path_data = Path(path_data)
7572
self.path_data = self._initialize_data(path_data)
7673
self.autosaver = Autosaver(str(path_data / Path('banks')))
74+
self.manager = self.autosaver.load(DeviceController.sys_effect)
75+
76+
# Controllers
7777
self.components = []
7878
self.controllers = self._load_controllers()
7979

8080
self._configure_controllers(self.controllers)
8181

82+
# Observers
83+
self.components_observer = ComponentsObserver(self.manager)
84+
current_pedalboard_observer = CurrentPedalboardObserver(self.controller(CurrentController))
85+
86+
self.manager.register(self.components_observer)
87+
self.manager.register(current_pedalboard_observer)
88+
8289
def _initialize(self, address, test=False):
8390
mod_host = ModHost(address)
8491
if test:
@@ -105,14 +112,9 @@ def _load_controllers(self):
105112
controllers = {}
106113

107114
list_controllers = [
108-
BanksController,
109115
ComponentDataController,
110116
CurrentController,
111117
DeviceController,
112-
EffectController,
113-
NotificationController,
114-
ParamController,
115-
PedalboardController,
116118
PluginsController,
117119
]
118120

@@ -128,16 +130,35 @@ def _configure_controllers(self, controllers):
128130

129131
def register(self, component):
130132
"""
131-
Register a :class:`Component` extended class into Application.
133+
Register a :class:`.Component` extended class into Application.
132134
The components will be loaded when application is loaded (after `start` method is called).
133135
134136
:param Component component: A module to be loaded when the Application is loaded
135137
"""
136138
self.components.append(component)
137139

140+
def register_observer(self, observer):
141+
"""
142+
Register a :class:`.ApplicationObserver` specialization into Application.
143+
The observer will receive calls when changes occurs in system, like
144+
banks creation, current pedalboard changes.
145+
146+
:param ApplicationObserver observer: The observer who will receive the changes notifications
147+
"""
148+
self.components_observer.register(observer)
149+
150+
def unregister_observer(self, observer):
151+
"""
152+
Unregister an observer in :class:`.Application`.
153+
The observer not will be more notified of the changes requested in the application API.
154+
155+
:param ApplicationObserver observer: The observer who will not receive further changes notification
156+
"""
157+
self.components_observer.unregister(observer)
158+
138159
def start(self):
139160
"""
140-
Start this API, initializing the components.
161+
Start the application, initializing your components.
141162
"""
142163
current_pedalboard = self.controller(CurrentController).pedalboard
143164
if current_pedalboard is None:
@@ -156,6 +177,9 @@ def start(self):
156177
atexit.register(self.stop)
157178

158179
def stop(self):
180+
"""
181+
Stop the application, closing your components.
182+
"""
159183
for component in self.components:
160184
component.close()
161185
self.log('Stopping component - {}', component.__class__.__name__)
@@ -186,4 +210,3 @@ def dao(self, dao):
186210

187211
def log(self, message, *args, **kwargs):
188212
logging.info(message.format(*args, **kwargs))
189-
#print('[' + time.strftime('%Y-%m-%d %H:%M:%S') + ']', *args, **kwargs)

application/component/application_observer.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
from abc import ABCMeta, abstractmethod
16-
from pluginsmanager.model.updates_observer import UpdatesObserver
16+
from pluginsmanager.observer.updates_observer import UpdatesObserver
1717

1818

1919
class ApplicationObserver(UpdatesObserver, metaclass=ABCMeta):
@@ -23,40 +23,15 @@ class ApplicationObserver(UpdatesObserver, metaclass=ABCMeta):
2323
Your methods are called when occurs any change in Bank, Pedalboard, Effect, etc.
2424
2525
To do this, it is necessary that the :class:`.ApplicationObserver` objects
26-
be registered in some manager, so that it reports the changes. An
27-
example of a manager is :class:`.NotificationController`.
28-
29-
:class:`.NotificationController`, comparing with, :class:`.UpdatesObserver`
30-
add TOKEN. Each observer should have a unique token. This token will differentiate who
31-
is making requests so the manager does not notify you back.
32-
33-
For example, if a component requires the manager to have an effect change its
34-
state (``effect.active = not effect.active``), it is not necessary for the manager
35-
to inform the component of the change. If the component was informed, it might not know
36-
that it was the one that requested the change and possibly would update its interface
37-
erroneously.
26+
be registered in application (using :meth:`.Application.register_observer`
27+
or :meth:`.Component.register_observer`), so that it reports the changes.
3828
"""
3929

40-
def __init__(self):
41-
super(ApplicationObserver, self).__init__()
42-
43-
@property
44-
@abstractmethod
45-
def token(self):
46-
"""
47-
Observer token identifier.
48-
49-
:return: string for token identifier or None if is not necessary identify the observer
50-
(it will receive all notification)
51-
"""
52-
pass
53-
5430
@abstractmethod
55-
def on_current_pedalboard_changed(self, pedalboard, token=None):
31+
def on_current_pedalboard_changed(self, pedalboard, **kwargs):
5632
"""
5733
Called when the current pedalboard is changed
5834
5935
:param Pedalboard pedalboard: New current pedalboard
60-
:param string token: Request token identifier
6136
"""
6237
pass

application/component/component.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

1515
from abc import ABCMeta, abstractmethod
1616

17-
from application.controller.notification_controller import NotificationController
18-
1917

2018
class Component(metaclass=ABCMeta):
2119

@@ -42,21 +40,16 @@ def controller(self, controller):
4240

4341
def register_observer(self, observer):
4442
"""
45-
Register an observer in :class:`.Application` by :class:`.NotificationController`.
46-
Observers will be notified of the changes requested in the application API.
47-
48-
Obs: If a observer contains a *token* and the request informs the same *token*
49-
the observer not will be notified.
43+
Calls :meth:`.Application.register_observer`.
5044
51-
:param UpdatesObserver observer:
45+
:param ApplicationObserver observer: The observer who will receive the changes notifications
5246
"""
53-
self.controller(NotificationController).register(observer)
47+
self.application.register_observer(observer)
5448

5549
def unregister_observer(self, observer):
5650
"""
57-
Unregister an observer in :class:`.Application` by :class:`.NotificationController`.
58-
The observer not will be more notified of the changes requested in the application API.
51+
Calls :meth:`.Application.unregister_observer`.
5952
60-
:param UpdatesObserver observer:
53+
:param ApplicationObserver observer: The observer who will not receive further changes notification
6154
"""
62-
self.controller(NotificationController).unregister(observer)
55+
self.application.unregister_observer(observer)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Copyright 2017 SrMouraSilva
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from application.component.application_observer import ApplicationObserver
16+
17+
18+
class ComponentsObserver(ApplicationObserver):
19+
20+
def __init__(self, manager):
21+
super(ComponentsObserver, self).__init__()
22+
self.observers = []
23+
self._manager = manager
24+
25+
def register(self, observer):
26+
self.observers.append(observer)
27+
observer.manager = self.manager
28+
29+
def unregister(self, observer):
30+
observer.manager = None
31+
self.observers.remove(observer)
32+
33+
@property
34+
def scope(self):
35+
return self._manager.observer_manager.scope
36+
37+
def on_bank_updated(self, bank, update_type, index, origin, **kwargs):
38+
for observer in self.observers:
39+
if observer != self.scope:
40+
observer.on_bank_updated(bank, update_type, index=index, origin=origin, **kwargs)
41+
42+
def on_pedalboard_updated(self, pedalboard, update_type, index, origin, **kwargs):
43+
for observer in self.observers:
44+
if observer != self.scope:
45+
observer.on_pedalboard_updated(pedalboard, update_type, index=index, origin=origin, **kwargs)
46+
47+
def on_effect_updated(self, effect, update_type, index, origin, **kwargs):
48+
for observer in self.observers:
49+
if observer != self.scope:
50+
observer.on_effect_updated(effect, update_type, index=index, origin=origin, **kwargs)
51+
52+
def on_effect_status_toggled(self, effect, **kwargs):
53+
for observer in self.observers:
54+
if observer != self.scope:
55+
observer.on_effect_status_toggled(effect, **kwargs)
56+
57+
def on_param_value_changed(self, param, **kwargs):
58+
for observer in self.observers:
59+
if observer != self.scope:
60+
observer.on_param_value_changed(param, **kwargs)
61+
62+
def on_connection_updated(self, connection, update_type, pedalboard, **kwargs):
63+
for observer in self.observers:
64+
if observer != self.scope:
65+
observer.on_connection_updated(connection, update_type, pedalboard=pedalboard, **kwargs)
66+
67+
def on_current_pedalboard_changed(self, pedalboard, **kwargs):
68+
for observer in self.observers:
69+
if observer != self.scope:
70+
observer.on_current_pedalboard_changed(pedalboard, **kwargs)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright 2017 SrMouraSilva
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from application.component.application_observer import ApplicationObserver
16+
from pluginsmanager.observer.update_type import UpdateType
17+
18+
19+
class CurrentPedalboardObserver(ApplicationObserver):
20+
"""
21+
This viewer allows change the current pedalboard
22+
if it is updated or removed or if your bank is updated or removed.
23+
"""
24+
25+
def __init__(self, current_controller):
26+
"""
27+
:param CurrentController current_controller:
28+
"""
29+
super(CurrentPedalboardObserver, self).__init__()
30+
self._current_controller = current_controller
31+
32+
def on_bank_updated(self, bank, update_type, index, origin, **kwargs):
33+
if update_type == UpdateType.UPDATED:
34+
old_bank = kwargs['old']
35+
if old_bank == self._current_controller.bank:
36+
self._current_controller.set_bank(bank, try_preserve_index=True)
37+
38+
elif update_type == UpdateType.DELETED:
39+
if bank == self._current_controller.bank:
40+
next_bank_index = self._current_controller.next_bank_index(index-1)
41+
new_current_bank = origin.banks[next_bank_index]
42+
43+
self._current_controller.set_bank(new_current_bank)
44+
45+
def on_pedalboard_updated(self, pedalboard, update_type, index, origin, **kwargs):
46+
if update_type == UpdateType.UPDATED:
47+
old_pedalboard = kwargs['old']
48+
49+
if pedalboard == self._current_controller.pedalboard \
50+
or old_pedalboard == self._current_controller.pedalboard:
51+
self._current_controller.set_pedalboard(pedalboard, notify=False, force=True)
52+
53+
def on_effect_status_toggled(self, effect, **kwargs):
54+
pass
55+
56+
def on_connection_updated(self, connection, update_type, pedalboard, **kwargs):
57+
pass
58+
59+
def on_param_value_changed(self, param, **kwargs):
60+
pass
61+
62+
def on_effect_updated(self, effect, update_type, index, origin, **kwargs):
63+
pass
64+
65+
def on_current_pedalboard_changed(self, pedalboard, **kwargs):
66+
pass

0 commit comments

Comments
 (0)