diff --git a/python/Gaffer/LocalDispatcher.py b/python/Gaffer/LocalDispatcher.py index f5a4c71d6f9..e7486c8ade9 100644 --- a/python/Gaffer/LocalDispatcher.py +++ b/python/Gaffer/LocalDispatcher.py @@ -109,6 +109,10 @@ def __backgroundDispatch( self, batch, scriptFile, messageTitle ) : script = batch.node().scriptNode() + if isinstance( batch.node(), Gaffer.TaskList ) : + IECore.msg( IECore.MessageHandler.Level.Info, messageTitle, "Finished " + batch.node().relativeName( script ) ) + return + taskContext = batch.context() frames = str( IECore.frameListFromList( [ int(x) for x in batch.frames() ] ) ) diff --git a/python/Gaffer/TaskList.py b/python/Gaffer/TaskList.py new file mode 100644 index 00000000000..ea4030066a5 --- /dev/null +++ b/python/Gaffer/TaskList.py @@ -0,0 +1,59 @@ +########################################################################## +# +# Copyright (c) 2014, Image Engine Design Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided with +# the distribution. +# +# * Neither the name of John Haddon nor the names of +# any other contributors to this software may be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +########################################################################## + +import os +import subprocess + +import IECore + +import Gaffer + +# Used to collect Executable tasks for dispatching all at once +class TaskList( Gaffer.ExecutableNode ) : + + def __init__( self, name = "TaskList" ) : + + Gaffer.ExecutableNode.__init__( self, name ) + + def hash( self, context ) : + + return IECore.MurmurHash() + + def execute( self ) : + + pass + +IECore.registerRunTimeTyped( TaskList, typeName = "Gaffer::TaskList" ) diff --git a/python/Gaffer/__init__.py b/python/Gaffer/__init__.py index d5c76e717b4..aeee2f2f736 100644 --- a/python/Gaffer/__init__.py +++ b/python/Gaffer/__init__.py @@ -66,5 +66,6 @@ from OutputRedirection import OutputRedirection from LocalDispatcher import LocalDispatcher from SystemCommand import SystemCommand +from TaskList import TaskList __import__( "IECore" ).loadConfig( "GAFFER_STARTUP_PATHS", {}, subdirectory = "Gaffer" ) diff --git a/python/GafferTest/TaskListTest.py b/python/GafferTest/TaskListTest.py new file mode 100644 index 00000000000..fbb4f8343e6 --- /dev/null +++ b/python/GafferTest/TaskListTest.py @@ -0,0 +1,71 @@ +########################################################################## +# +# Copyright (c) 2014, Image Engine Design Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided with +# the distribution. +# +# * Neither the name of John Haddon nor the names of +# any other contributors to this software may be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +########################################################################## + +import os +import unittest + +import IECore + +import Gaffer +import GafferTest + +class TaskListTest( GafferTest.TestCase ) : + + def test( self ) : + + n = Gaffer.TaskList() + c = Gaffer.Context() + c2 = Gaffer.Context() + c2["frame"] = 10.0 + self.assertEqual( n.hash( c ), n.hash( c2 ) ) + + n2 = Gaffer.TaskList( "TaskList2" ) + self.assertEqual( n.hash( c ), n2.hash( c ) ) + self.assertEqual( n.hash( c2 ), n2.hash( c2 ) ) + + def setUp( self ) : + + for f in [ "/tmp/systemCommandTest.txt" ] : + if os.path.exists( f ) : + os.remove( f ) + + def tearDown( self ) : + + self.setUp() + +if __name__ == "__main__": + unittest.main() + diff --git a/python/GafferTest/__init__.py b/python/GafferTest/__init__.py index 9bbe353f771..6b1981b1690 100644 --- a/python/GafferTest/__init__.py +++ b/python/GafferTest/__init__.py @@ -136,6 +136,7 @@ def wrapper( self ) : from MetadataTest import MetadataTest from StringAlgoTest import StringAlgoTest from SystemCommandTest import SystemCommandTest +from TaskListTest import TaskListTest if __name__ == "__main__": import unittest diff --git a/python/GafferUI/TaskListUI.py b/python/GafferUI/TaskListUI.py new file mode 100644 index 00000000000..1b2c92029cf --- /dev/null +++ b/python/GafferUI/TaskListUI.py @@ -0,0 +1,46 @@ +########################################################################## +# +# Copyright (c) 2014, Image Engine Design Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided with +# the distribution. +# +# * Neither the name of John Haddon nor the names of +# any other contributors to this software may be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +########################################################################## + +import Gaffer +import GafferUI + +Gaffer.Metadata.registerNodeDescription( + +Gaffer.TaskList, + +"""Used to collect Executable tasks for dispatching all at once""", + +) diff --git a/src/Gaffer/Dispatcher.cpp b/src/Gaffer/Dispatcher.cpp index 0cacb16e90d..b07fca4af19 100644 --- a/src/Gaffer/Dispatcher.cpp +++ b/src/Gaffer/Dispatcher.cpp @@ -402,14 +402,22 @@ Dispatcher::TaskBatchPtr Dispatcher::acquireBatch( const ExecutableNode::Task &t } } - tasksToBatches[taskHash] = batch; + if ( taskHash != MurmurHash() ) + { + tasksToBatches[taskHash] = batch; + } + return batch; } } TaskBatchPtr batch = new TaskBatch( task ); currentBatches[hash] = batch; - tasksToBatches[taskHash] = batch; + if ( taskHash != MurmurHash() ) + { + tasksToBatches[taskHash] = batch; + } + return batch; } diff --git a/startup/gui/menus.py b/startup/gui/menus.py index f3d813c7683..4cfc188ab82 100644 --- a/startup/gui/menus.py +++ b/startup/gui/menus.py @@ -280,3 +280,4 @@ def __shaderNodeCreator( nodeName, shaderName ) : nodeMenu.append( "/Utility/Reference", GafferUI.ReferenceUI.nodeMenuCreateCommand ) nodeMenu.definition().append( "/Utility/Backdrop", { "command" : GafferUI.BackdropUI.nodeMenuCreateCommand } ) nodeMenu.append( "/Utility/System Command", Gaffer.SystemCommand, searchText = "SystemCommand" ) +nodeMenu.append( "/Utility/Task List", Gaffer.TaskList, searchText = "TaskList" )