Skip to content
This repository has been archived by the owner on May 28, 2022. It is now read-only.

Fix #588 - Refactor plugins. #589

Closed

Conversation

FranciscoCanas
Copy link
Member

  • 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
Copy link
Member

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.

Copy link
Member

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.

@FranciscoCanas FranciscoCanas changed the title WIP #588 - Refactor jackaudio plugins. WIP #588 - Refactor plugins. Sep 20, 2014
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()])
Copy link
Member

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.

Copy link
Member Author

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).

Copy link
Member

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.

@dideler dideler added this to the 2014 Fall - UCOSP milestone Sep 22, 2014
@FranciscoCanas
Copy link
Member Author

Should the Configs be persisted to plugin.conf even when the user doesn't change any of the default values for that config?

@FranciscoCanas FranciscoCanas force-pushed the 588-refactor-plugins branch 2 times, most recently from 9485607 to 08ced34 Compare October 4, 2014 20:12
@FranciscoCanas FranciscoCanas changed the title WIP #588 - Refactor plugins. Fix #588 - Refactor plugins. Oct 15, 2014
try:
source = self.config.source
except OptionValueNotSetError:
source = None
Copy link
Member

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 ''.

@mtomwing
Copy link
Member

There are a lot more places where ConfigurablePluginManager is used. You'll have to remove anything that interacts with it or plugin.conf directly.

@FranciscoCanas
Copy link
Member Author

@mtomwing:
I found that PluginManager's set_plugin_option and get_plugin_option still use ConfigurablePluginManager, so I would like to reimplement them using the Config class.

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):
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member

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)
Copy link
Member

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)

@mtomwing
Copy link
Member

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.

@FranciscoCanas
Copy link
Member Author

I can look into it this afternoon. If you have time, let me know how to reproduce it.

@mtomwing
Copy link
Member

IIRC:

  1. nuke freeseer configs
  2. start freeseer, open config tool
  3. change video input mixer to pip
  4. press setup for pip
  5. check ~/.freeseer/profiles/default/plugin.conf and see that there is only 1 video test input instance
  6. change the secondary pip input to something else, and then back to the test input
  7. plugin.conf now has both 0 and 1 instances

@FranciscoCanas
Copy link
Member Author

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.

@mtomwing
Copy link
Member

There's probably a missing plugin_object.set_instance(1) somewhere. -_-

@FranciscoCanas
Copy link
Member Author

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.

@mtomwing
Copy link
Member

Ah, then it's likely missing a plugin_object.load_config(...) after that set_instance(1). Try adding a self.load_config(...) to set_instance and see if that fixes it.

@FranciscoCanas
Copy link
Member Author

That does fix it. :) I spent way too long stepping through code trying to find why it was loading the same config instance. :P

@mtomwing
Copy link
Member

Would you mind submitting another PR for that fix since it also exists in master (or at least I think it does)?

@FranciscoCanas
Copy link
Member Author

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.

@mtomwing
Copy link
Member

Okay, leave it here then. Can you play around with the other mixers and make sure they're all good?

@FranciscoCanas
Copy link
Member Author

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.

@mtomwing
Copy link
Member

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__)))
Copy link
Member

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.

@mtomwing
Copy link
Member

Looks good to go now. I'll merge whenever you have time to squash your commits again.

@FranciscoCanas FranciscoCanas force-pushed the 588-refactor-plugins branch 2 times, most recently from b58b6f8 to 6ea813a Compare October 25, 2014 23:42
@mtomwing
Copy link
Member

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
@mtomwing
Copy link
Member

Merged in 9a9f2a3.

Thanks for your contribution!

@mtomwing mtomwing closed this Oct 26, 2014
@FranciscoCanas
Copy link
Member Author

Thanks for all the feedback!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants