Dependency injection was deprecated from 1.3 onwards in favour of explicit plug-ins - ContextPlugin
and InstancePlugin
.
For this to work, we could potentially make it ContextAction
and InstanceAction
.
Dependency injection was deprecated from 1.3 onwards in favour of explicit plug-ins - ContextPlugin
and InstancePlugin
.
For this to work, we could potentially make it ContextAction
and InstanceAction
.
You are right, thought there was something I was missing:)
+1
Makes sense to me.
Feel free to make it a feature issue, should be fairly straightforward to implement.
In theory would an InstanceAction
be executable from an instance as well? Ei. right-click on an instance, and select the action.
Not sure about that. How would you associate this action with the Instance?
And if you were doing something like this…
instance.append(MyAction)
What would it mean for it to be a ContextAction
or InstanceAction
? Mind blown?
This is where instance actions could come in, but the logic for having an action on an instance would be different than an action on a plugin iterating over instances. Is that right, @marcus?
I don’t know, there are probably more than one way of going at it. Feel free to propose your ideas. Maybe start with a few examples of actions you would expect to find on an instance?
First would probably be a select action:
class SelectInstance(pyblish.api.InstanceAction):
label = 'Select'
on = 'all'
def process(self, instance):
pymel.core.select(instance[0])
You would assign the action when collecting the instance:
class CollectLocators(pyblish.api.ContextPlugin):
order = pyblish.api.CollectorOrder
def process(self, context):
for node in pymel.core.ls(type='locator'):
instance = context.add_instance(node.name(), family='locator')
instance.actions.append(SelectInstance)
That looks great, I think.
It also might make sense that it is an InstanceAction
, in which instance
in the argument signature is the right-clicked instance in the view. A ContextAction
could take context
, and pretty much still make sense, right?
The assignment also works for me.
I think let’s mock it up. It’d need the ContextAction
and InstanceAction
classes in pyblish-base
, to be formatted in pyblish-rpc
and finally drawn in pyblish-qml
. There is already actions in each project to use for reference and in all should be quite straightforward to implement.
Does it make sense as well that if an InstanceAction
assigned to an instance is run once, and an InstanceAction
assigned to a plugin will potentially be run multiple times?
Spontaneously, yes I think it does.
Referencing the original issue for completeness.
Slight adjustment to @BigRoy code, since the context returns None.
# pseudocode
def process(self, context, plugin):
# Get the errored instances
failed = []
for result in context.data["results"]:
if result["error"] is not None and result["instance"] is not None:
failed.append(result["instance"])
# Apply pyblish.logic to get the instances for the plug-in
instances = pyblish.api.instances_by_plugin(failed, plugin)
If an Action is only available on failed
would this also be a problem? I’m assuming it wouldn’t be because it’ll only fail with errors.
# pseudocode
class MyAction(pyblish.api.Action):
on = "failed"
Doesn’t seem to be a problem
A problem how?
The result["error"]
or result["instance"]
being None.
I just pulled the latest repos to test Action icons and indeed found these returning None. It’s strange that before it did actually work and run through the code. Was it ignoring the context maybe? Anyway, thanks @tokejepsen, checking for None works as expected.
Were they returning None
even when there was an error, you mean? If you can post a reproducible, that would be perfect.
Yes, well… the others (other instances) returned None. Say you run an Action and have two instances. One of them fails, the other succeeds. Because the first failed the Action becomes available. If you run the Action then the other instance will still be iterated and would have result["error"] is None
so you’d have to ensure you’re catching that.
Similarly in any Action the result["instance"] is None
at least once because of the “Context” being iterated (if I understood @tokejepsen correctly). I think this is new behavior since I can’t recall having that problem before.
Does that help?