Skip to content

Commit

Permalink
Merge pull request #1871 from pupil-labs/replace_uniq_by_class
Browse files Browse the repository at this point in the history
Allow replacing `by_class` unique plugins
  • Loading branch information
papr authored May 20, 2020
2 parents a8b18f5 + 1ebe8ec commit 4b4ee9d
Showing 1 changed file with 41 additions and 23 deletions.
64 changes: 41 additions & 23 deletions pupil_src/shared_modules/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
---------------------------------------------------------------------------~(*)
"""

import importlib
import logging
import os
import sys
import importlib
from time import time
import logging

logger = logging.getLogger(__name__)
"""
Expand Down Expand Up @@ -350,31 +350,13 @@ def __iter__(self):
def __str__(self):
return "Plugin List: {}".format(self._plugins)

def add(self, new_plugin, args={}):
def add(self, new_plugin_cls, args={}):
"""
add a plugin instance to the list.
"""
if new_plugin.uniqueness == "by_base_class":
for p in self._plugins:
if p.base_class == new_plugin.__bases__[-1]:
replc_str = "Plugin {} of base class {} will be replaced by {}."
logger.debug(
replc_str.format(p, p.base_class_name, new_plugin.__name__)
)
p.alive = False
self.clean()

elif new_plugin.uniqueness == "by_class":
for p in self._plugins:
if p.this_class == new_plugin:
logger.warning(
"Plugin '{}' is already loaded . Did not add it.".format(
new_plugin.__name__
)
)
return
self._find_and_remove_duplicates(new_plugin_cls)

plugin_instance = new_plugin(self.g_pool, **args)
plugin_instance = new_plugin_cls(self.g_pool, **args)
if not plugin_instance.alive:
logger.warning("plugin failed to initialize")
return
Expand All @@ -385,6 +367,42 @@ def add(self, new_plugin, args={}):
if self.g_pool.app in ("capture", "player"):
plugin_instance.init_ui()

def _find_and_remove_duplicates(self, new_plugin_cls):
for duplicate in self._duplicates(new_plugin_cls):
self._remove_duplicated_instance(duplicate)

def _duplicates(self, new_plugin_cls):
if new_plugin_cls.uniqueness == "by_base_class":
yield from self._duplicates_by_rule(
self._has_same_base_class, new_plugin_cls
)
elif new_plugin_cls.uniqueness == "by_class":
yield from self._duplicates_by_rule(self._is_same_class, new_plugin_cls)

def _duplicates_by_rule(self, is_duplicate_rule, new_plugin_cls):
duplicates = (
old_plugin_inst
for old_plugin_inst in self._plugins
if is_duplicate_rule(old_plugin_inst, new_plugin_cls)
)
yield from duplicates

def _remove_duplicated_instance(self, duplicated_plugin_inst):
name = duplicated_plugin_inst.pretty_class_name
uniq = duplicated_plugin_inst.uniqueness
message = f"Replacing {name} due to '{uniq}' uniqueness"
logger.debug(message)
duplicated_plugin_inst.alive = False
self.clean()

@staticmethod
def _has_same_base_class(old_plugin_inst, new_plugin_cls):
return old_plugin_inst.base_class == new_plugin_cls.__bases__[-1]

@staticmethod
def _is_same_class(old_plugin_inst, new_plugin_cls):
return old_plugin_inst.this_class == new_plugin_cls

def clean(self):
"""
plugins may flag themselves as dead or are flagged as dead. We need to remove them.
Expand Down

0 comments on commit 4b4ee9d

Please sign in to comment.