pyblish / pyblish-qml

Pyblish QML frontend for Maya 2013+, Houdini 11+, Nuke 8+ and more
GNU Lesser General Public License v3.0
114 stars 44 forks source link

Implementing "Post Collect" #356

Open davidlatwe opened 4 years ago

davidlatwe commented 4 years ago

This PR should resolves pyblish/pyblish-base#359, an experimental feature called "Post Collect".

The "Post Collect" is a GUI behavior that will make Pyblish-QML stop running collector plugins at a given point, and let user to decide which instance may continue to the rest CVEI and which not.

Usage

Require an extra environment variable PYBLISH_QML_POST_COLLECT to provide the break point, the value is a string of float. The number shoule be inside the range of Pyblish's Collecting.

Here's an example: https://gist.github.com/davidlatwe/9c39e5ef05140d6ba98f0914ed46f5ed

And the working result:

post-collect-new

BigRoy commented 4 years ago

Lovely. This does seem to work for my use case - I'll have to clean up and rewrite the code again but definitely seems to cover the right basics of what I need.

davidlatwe commented 4 years ago

Nevertheless, it feels a bit odd that it would solely be a thing for Pyblish QML and their being no API equivalent to this feature in pyblish-base - so that makes me a bit wary about the implementation details.

Yeah, not sure it's about threading or other historical reason, both pyblish-lite and -qml were end up implementing their own plugin-instance iterator that behaves just like pyblish-base.

So since this feature was about controlling the iteration of plugins and instances, no need to touch pyblish-base to make a prototype.

If the out come was good, we could implement it back to pyblish-base. ☺️

BigRoy commented 4 years ago

So I've found a bug with this implementation.

  1. Have an Instance that is active by default and will trigger specific Additional Post Collectors...
  2. Then after initial Collecting, tick off the Instance. (disable it)
  3. Continue processing.

The Additional Post Collector is NOT visible in the user interface, however it will trigger. You will also see the "Additional" header remain there and flicker dark during processing, you just won't see the Plug-ins whatsoever.

This seems to happen whenever the Plugin's order is within 0.05 range of the post collect order.

How I set the PYBLISH_QML_POST_COLLECT

    post_collector_order = str(pyblish.api.CollectorOrder + 0.3)
    os.environ["PYBLISH_QML_POST_COLLECT"] = post_collector_order
class Collector(pyblish.api.ContextPlugin):

    order = pyblish.api.CollectorOrder
    label = "Collect"

    def process(self, context):

        new = context.create_instance(subset)
        new.data["family"] = "family"

class PostCollector(pyblish.api.InstancePlugin):
    order = pyblish.api.CollectorOrder + 0.3
    label = "Postcollect"
    families = ["*"]

    def process(self, instance):

        # show signs of life
        instance.context.create_instance("invalid")
        self.log.info("invalid!")
        print("invalid")
        raise RuntimeError("invalid!")

It will trigger when the PostCollector's order is anywhere between 0.3 and 0.349 (when it's 0.35 it works fine) almost as if it gets rounded off somewhere.

@davidlatwe can you reproduce this behavior?

BigRoy commented 4 years ago

Actually... it seems slightly different. It will always process the first plug-in that was set to run in the post-collectors, even when it shouldn't run for a current instance due to it being deactivated.

So say you'd deactivate nothing then the first one will still process when you deactivate the related instances and it "disappears in the UI". It will still run.

davidlatwe commented 4 years ago

So I've found a bug with this implementation.

Ok, I think I have fixed the bug ! The problem was at the post_collect that it didn't update plugins and context's toggle state before running them.

Please have a test @BigRoy ☺️