-
Notifications
You must be signed in to change notification settings - Fork 110
Fix #588 - Refactor plugins. #589
Fix #588 - Refactor plugins. #589
Conversation
FranciscoCanas
commented
Sep 20, 2014
- Added settings.py with PluginConfig.
- Rewrote jackaudio's load_init()
self.client = config.client | ||
self.connect = config.connect | ||
self.server = config.server | ||
self.clientname = config.clientname |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to store any of these values as they can be accessed directly from config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll also add that there's a way to make Config objects automatically persist their values on change.
self.plugman.set_plugin_option(self.CATEGORY, self.get_config_name(), "Server", self.server) | ||
self.plugman.set_plugin_option(self.CATEGORY, self.get_config_name(), "ClientName", self.clientname) | ||
profile = settings.profile_manager.get() | ||
config = profile.get_config('plugin.conf', JackAudioConfig, storage_args=[self.get_config_name()]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A plugin shouldn't need to know about profiles or anything - all it cares about is its Config class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the plugin be reading from the plugin.conf file here though? In which case, would it need to know the profile so that it can read the plugin.conf file from the correct file (ie ~/.freeseer/profiles//plugin.conf).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was getting at. A plugin shouldn't be loading its config here - it should be loaded as part of whatever is using the Plugin. This way there's less coupling between a plugin and where its config comes from.
Should the Configs be persisted to plugin.conf even when the user doesn't change any of the default values for that config? |
9485607
to
08ced34
Compare
fd02b69
to
0a600ff
Compare
try: | ||
source = self.config.source | ||
except OptionValueNotSetError: | ||
source = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be possible for self.config.source
to be not set since it has a default value of ''
.
There are a lot more places where |
@mtomwing: However, I don't see of a way to read the values of an option from an instance of Config using only the name of the option. Config.get_value() requires the option instance itself as an argument. Is there a specific way I can map from an option's string name -> option's value? |
self.set_plugin_option("VideoMixer", "Video Passthrough-0", "Video Input", "Video Test Source") | ||
self.save() | ||
log.info("Default plugins enabled.") | ||
|
||
def get_plugin_option(self, category, name, option): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are get_plugin_option
and set_plugin_option
actually used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're not used now, but I was thinking they may be used in the configuration endpoints.
Maybe it would make more sense to get/set config options directly on a plugin instance rather then through PluginManager's get/set_plugin_option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that would make more sense.
self.plugman.save() | ||
log.debug('Set pulseaudio source to %s' % self.source) | ||
self.config.source = self.widget.source_combobox.itemData(index).toString() | ||
log.debug('Set pulseaudio source to %s' % self.config.source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.debug('message with arg %s', arg1)
2841c72
to
a90afe2
Compare
It's going to take me another day or so to completely vet the changes. There appears to be a bug with the mixer plugin configs but I'm not entirely sure if it exists in master too. |
I can look into it this afternoon. If you have time, let me know how to reproduce it. |
IIRC:
|
On my branch, the behavior I see when following the steps described above is that the 2nd video test input instance is not being added to the plugin.conf file: I spent some time debugging this, and to me it looks like the self.config instance for the two video test sources is actually shared. the 'storage_args' argument that Config uses to hold the name by which to save to file is the same for both: 'Video Test Source-0'. So when I change settings for the pip input, self.config.save() saves it to 'Video Test Source-0' still. Will update more later. |
There's probably a missing |
That's what I thought at first too, but the .set_instance(1) does get called when you update a setting on the pip input Test Video Source. So the plugin object has instance = 1. But when it gets to the config.save(), the config.save() still retains that 'Video Test Source-0' in its storage_args and so it just overwrites that entry. |
Ah, then it's likely missing a |
That does fix it. :) I spent way too long stepping through code trying to find why it was loading the same config instance. :P |
Would you mind submitting another PR for that fix since it also exists in master (or at least I think it does)? |
On master the behaviour was a bit different: It creates a new instance, but only once you have changed some setting in the pip input's video test source so that it's different than the main input's test source. I'm not sure if that's by design or not. I can still open an PR, since this changes the behaviour. |
Okay, leave it here then. Can you play around with the other mixers and make sure they're all good? |
I noticed another quirk: For the pulsesrc plugin (and possibly others with similar drop-down widget and default values), I have noticed that we only call its set_source() handler when the drop-down option changes. If the user opens pulsesrc settings widget but closes it again without changing anything then we don't save the current selection. We save the default, which is currently an empty string. So it's unintuitive: it looks like you have the right source selected, but it doesn't save it until you change it. This behaviour is actually the same in master branch currently. |
Okay, that definitely deserves an issue of its own. Would you mind creating one with your findings? I'll look into merging this refactor tonight now that the set_instance thing is sorted. Maybe one day Freeseer will have a good manager that doesn't treat plugins as singletons. |
# Get the path where the installed plugins are located on systems where | ||
# freeseer is installed. | ||
pluginpath = "%s/../plugins" % os.path.dirname(os.path.abspath(__file__)) | ||
pluginpath = "{}/../plugins".format(os.path.dirname(os.path.abspath(__file__))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess if this is going to be changed, it may as well also use os.path.join
too.
Looks good to go now. I'll merge whenever you have time to squash your commits again. |
b58b6f8
to
6ea813a
Compare
How about, "Fix #588 Refactor plugins to use Config framework"? |
Each plugin class that saves configuration settings to the plugin.conf file now has its own CONFIG_CLASS that extends the Config class from the freeseer.framework.config.core package Plugin options are loaded and saved from/to file via the plugin's Config class. Changes the YAPSY ConfigurablePluginManager to simple PluginManager. Refactored plugins: - Jackaudio - PulseSrcAudio - Multiaudio - DesktopLinuxSrc - Firewiresrc - Usbsrc - Videotestsrc - Picture-in-Picture (pip) - Videopassthrough - Audiofeedback - Ogg Icecast - Ogg output - Videopreview - RTMP Stream
6ea813a
to
d13a0b2
Compare
Merged in 9a9f2a3. Thanks for your contribution! |
Thanks for all the feedback! |