diff --git a/Changes.md b/Changes.md index 77921afb0fc..c30f751a995 100644 --- a/Changes.md +++ b/Changes.md @@ -110,6 +110,7 @@ API - Handle::AngularDrag : Added `isLinearDrag()` method. - Widget : Added per-widget control over colour display transforms via new `setDisplayTransform()`, `getDisplayTransform()` and `displayTransform()` methods. - VisibleSet : Added `VisibleSet::Visibility` struct containing `drawMode` and `descendantsVisible` members. +- ValuePlug : Improved `getValue()` performance, particularly when retrieving previously computed values from the cache. One benchmark shows a 50% reduction in runtime when the cache is under heavy contention from many threads. Breaking Changes ---------------- @@ -160,6 +161,8 @@ Breaking Changes - gaffer test : Replaced `-performanceOnly` flag with `-category` argument which may be set to `performance` for the same as the old `-performanceOnly`, or `standard` for the converse. - VisibleSet : Renamed `VisibleSet::match()` to `visibility()` and changed return type. - SceneView : Removed `gridPlug()` method. +- TypedPlug : Moved implementation code from `TypedPlug.inl` to `TypedPlugImplementation.h`. +- TypedObjectPlug : Moved implementation code from `TypedObjectPlug.inl` to `TypedObjectPlugImplementation.h`. Build ----- diff --git a/SConstruct b/SConstruct index 8dce6cd3837..83e304fdb53 100644 --- a/SConstruct +++ b/SConstruct @@ -1093,7 +1093,7 @@ libraries = { "GafferSceneTest" : { "envAppends" : { - "LIBS" : [ "Gaffer", "GafferDispatch", "GafferScene", "IECoreScene$CORTEX_LIB_SUFFIX" ], + "LIBS" : [ "Gaffer", "GafferDispatch", "GafferScene", "GafferImage", "IECoreScene$CORTEX_LIB_SUFFIX" ], }, "pythonEnvAppends" : { "LIBS" : [ "Gaffer", "GafferDispatch", "GafferBindings", "GafferScene", "GafferSceneTest" ], @@ -1106,7 +1106,7 @@ libraries = { "LIBS" : [ "Gaffer", "GafferUI", "GafferImage", "GafferImageUI", "GafferScene", "Iex$IMATH_LIB_SUFFIX", "IECoreGL$CORTEX_LIB_SUFFIX", "IECoreImage$CORTEX_LIB_SUFFIX", "IECoreScene$CORTEX_LIB_SUFFIX" ], }, "pythonEnvAppends" : { - "LIBS" : [ "IECoreGL$CORTEX_LIB_SUFFIX", "GafferBindings", "GafferScene", "GafferUI", "GafferImageUI", "GafferSceneUI", "IECoreScene$CORTEX_LIB_SUFFIX" ], + "LIBS" : [ "IECoreGL$CORTEX_LIB_SUFFIX", "GafferBindings", "GafferScene", "GafferImage", "GafferUI", "GafferImageUI", "GafferSceneUI", "IECoreScene$CORTEX_LIB_SUFFIX" ], }, }, @@ -1246,7 +1246,7 @@ libraries = { "GafferOSLUI" : { "envAppends" : { - "LIBS" : [ "Gaffer", "GafferUI", "GafferOSL" ], + "LIBS" : [ "Gaffer", "GafferImage", "GafferUI", "GafferOSL" ], }, "pythonEnvAppends" : { "LIBS" : [ "IECoreGL$CORTEX_LIB_SUFFIX", "GafferBindings", "GafferScene", "GafferUI", "GafferImageUI", "GafferOSLUI" ], @@ -1351,7 +1351,7 @@ libraries = { "GafferUSD" : { "envAppends" : { - "LIBS" : [ "Gaffer", "GafferDispatch", "GafferScene", "IECoreScene$CORTEX_LIB_SUFFIX" ] + [ "${USD_LIB_PREFIX}" + x for x in ( [ "sdf", "arch", "tf", "vt" ] if not env["USD_MONOLITHIC"] else [ "usd_ms" ] ) ], + "LIBS" : [ "Gaffer", "GafferDispatch", "GafferScene", "GafferImage", "IECoreScene$CORTEX_LIB_SUFFIX" ] + [ "${USD_LIB_PREFIX}" + x for x in ( [ "sdf", "arch", "tf", "vt" ] if not env["USD_MONOLITHIC"] else [ "usd_ms" ] ) ], # USD includes "at least one deprecated or antiquated header", so we # have to drop our usual strict warning levels. "CXXFLAGS" : [ "-Wno-deprecated" if env["PLATFORM"] != "win32" else "/wd4996" ], diff --git a/include/Gaffer/NumericPlug.h b/include/Gaffer/NumericPlug.h index fab3d059341..c0eec8f5ad3 100644 --- a/include/Gaffer/NumericPlug.h +++ b/include/Gaffer/NumericPlug.h @@ -45,7 +45,7 @@ namespace Gaffer { template -class GAFFER_API NumericPlug : public ValuePlug +class IECORE_EXPORT NumericPlug : public ValuePlug { public : @@ -103,3 +103,5 @@ IE_CORE_DECLAREPTR( FloatPlug ); IE_CORE_DECLAREPTR( IntPlug ); } // namespace Gaffer + +#include "Gaffer/NumericPlug.inl" diff --git a/include/Gaffer/NumericPlug.inl b/include/Gaffer/NumericPlug.inl new file mode 100644 index 00000000000..9abd8016249 --- /dev/null +++ b/include/Gaffer/NumericPlug.inl @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2023, Cinesite VFX Ltd. 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. +// +////////////////////////////////////////////////////////////////////////// + +#pragma once + +namespace Gaffer +{ + +template +inline T NumericPlug::getValue( const IECore::MurmurHash *precomputedHash ) const +{ + return getObjectValue( precomputedHash )->readable(); +} + +} // namespace Gaffer diff --git a/include/Gaffer/Plug.inl b/include/Gaffer/Plug.inl index 4a9ab15d341..2122e37a356 100644 --- a/include/Gaffer/Plug.inl +++ b/include/Gaffer/Plug.inl @@ -37,9 +37,26 @@ #pragma once +#include "Gaffer/Node.h" + namespace Gaffer { +inline Node *Plug::node() +{ + return ancestor(); +} + +inline const Node *Plug::node() const +{ + return ancestor(); +} + +inline Plug::Direction Plug::direction() const +{ + return m_direction; +} + template T *Plug::getInput() { @@ -52,7 +69,6 @@ const T *Plug::getInput() const return IECore::runTimeCast( m_input ); } - template T *Plug::source() { diff --git a/include/Gaffer/TypedObjectPlug.h b/include/Gaffer/TypedObjectPlug.h index 0938bd5f2e1..8996d173653 100644 --- a/include/Gaffer/TypedObjectPlug.h +++ b/include/Gaffer/TypedObjectPlug.h @@ -181,3 +181,5 @@ IE_CORE_DECLAREPTR( AtomicCompoundDataPlug ); IE_CORE_DECLAREPTR( PathMatcherDataPlug ); } // namespace Gaffer + +#include "TypedObjectPlug.inl" diff --git a/include/Gaffer/TypedObjectPlug.inl b/include/Gaffer/TypedObjectPlug.inl index 334c5c6d7b7..6975e5cb872 100644 --- a/include/Gaffer/TypedObjectPlug.inl +++ b/include/Gaffer/TypedObjectPlug.inl @@ -1,7 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2011-2012, John Haddon. All rights reserved. -// Copyright (c) 2011-2015, Image Engine Design Inc. All rights reserved. +// Copyright (c) 2023, Cinesite VFX Ltd. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -35,84 +34,15 @@ // ////////////////////////////////////////////////////////////////////////// -/// This file contains the implementation of TypedObjectPlug. Rather than include it -/// in a public header it is #included in TypedObjectPlug.cpp, and the relevant template -/// classes are explicitly instantiated there. This prevents a host of problems to do with -/// the definition of the same symbols in multiple object files. Additional TypedObjectPlug -/// instantations may be created in similar .cpp files in other libraries. +#pragma once namespace Gaffer { template -const IECore::RunTimeTyped::TypeDescription > TypedObjectPlug::g_typeDescription; - -template -TypedObjectPlug::TypedObjectPlug( - const std::string &name, - Direction direction, - ConstValuePtr defaultValue, - unsigned flags -) - : ValuePlug( name, direction, defaultValue->copy(), flags ) -{ -} - -template -TypedObjectPlug::~TypedObjectPlug() -{ -} - -template -bool TypedObjectPlug::acceptsInput( const Plug *input ) const -{ - if( !ValuePlug::acceptsInput( input ) ) - { - return false; - } - if( input ) - { - return input->isInstanceOf( staticTypeId() ); - } - return true; -} - -template -PlugPtr TypedObjectPlug::createCounterpart( const std::string &name, Direction direction ) const -{ - return new TypedObjectPlug( name, direction, defaultValue(), getFlags() ); -} - -template -const typename TypedObjectPlug::ValueType *TypedObjectPlug::defaultValue() const -{ - return static_cast( defaultObjectValue() ); -} - -template -void TypedObjectPlug::setValue( ConstValuePtr value ) -{ - setObjectValue( value ); -} - -template -typename TypedObjectPlug::ConstValuePtr TypedObjectPlug::getValue( const IECore::MurmurHash *precomputedHash ) const +inline typename TypedObjectPlug::ConstValuePtr TypedObjectPlug::getValue( const IECore::MurmurHash *precomputedHash ) const { return getObjectValue( precomputedHash ); } -template -void TypedObjectPlug::setFrom( const ValuePlug *other ) -{ - const TypedObjectPlug *tOther = IECore::runTimeCast( other ); - if( tOther ) - { - setValue( tOther->getValue() ); - } - else - { - throw IECore::Exception( "Unsupported plug type" ); - } -} - } // namespace Gaffer diff --git a/include/Gaffer/TypedObjectPlugImplementation.h b/include/Gaffer/TypedObjectPlugImplementation.h new file mode 100644 index 00000000000..cfe0b3ff0d2 --- /dev/null +++ b/include/Gaffer/TypedObjectPlugImplementation.h @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2011-2012, John Haddon. All rights reserved. +// Copyright (c) 2011-2015, 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. +// +////////////////////////////////////////////////////////////////////////// + +/// This file contains the implementation of TypedObjectPlug. Rather than include it +/// in a public header it is #included in TypedObjectPlug.cpp, and the relevant template +/// classes are explicitly instantiated there. This prevents a host of problems to do with +/// the definition of the same symbols in multiple object files. Additional TypedObjectPlug +/// instantations may be created in similar .cpp files in other libraries. + +namespace Gaffer +{ + +template +const IECore::RunTimeTyped::TypeDescription > TypedObjectPlug::g_typeDescription; + +template +TypedObjectPlug::TypedObjectPlug( + const std::string &name, + Direction direction, + ConstValuePtr defaultValue, + unsigned flags +) + : ValuePlug( name, direction, defaultValue->copy(), flags ) +{ +} + +template +TypedObjectPlug::~TypedObjectPlug() +{ +} + +template +bool TypedObjectPlug::acceptsInput( const Plug *input ) const +{ + if( !ValuePlug::acceptsInput( input ) ) + { + return false; + } + if( input ) + { + return input->isInstanceOf( staticTypeId() ); + } + return true; +} + +template +PlugPtr TypedObjectPlug::createCounterpart( const std::string &name, Direction direction ) const +{ + return new TypedObjectPlug( name, direction, defaultValue(), getFlags() ); +} + +template +const typename TypedObjectPlug::ValueType *TypedObjectPlug::defaultValue() const +{ + return static_cast( defaultObjectValue() ); +} + +template +void TypedObjectPlug::setValue( ConstValuePtr value ) +{ + setObjectValue( value ); +} + +template +void TypedObjectPlug::setFrom( const ValuePlug *other ) +{ + const TypedObjectPlug *tOther = IECore::runTimeCast( other ); + if( tOther ) + { + setValue( tOther->getValue() ); + } + else + { + throw IECore::Exception( "Unsupported plug type" ); + } +} + +} // namespace Gaffer diff --git a/include/Gaffer/TypedPlug.h b/include/Gaffer/TypedPlug.h index bf8eb1d9951..c8e70e37c68 100644 --- a/include/Gaffer/TypedPlug.h +++ b/include/Gaffer/TypedPlug.h @@ -107,3 +107,5 @@ IE_CORE_DECLAREPTR( AtomicBox3fPlug ); IE_CORE_DECLAREPTR( AtomicBox2iPlug ); } // namespace Gaffer + +#include "Gaffer/TypedPlug.inl" diff --git a/include/Gaffer/TypedPlug.inl b/include/Gaffer/TypedPlug.inl index b392cb9b992..0fc9033ae71 100644 --- a/include/Gaffer/TypedPlug.inl +++ b/include/Gaffer/TypedPlug.inl @@ -1,7 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2011-2012, John Haddon. All rights reserved. -// Copyright (c) 2011-2013, Image Engine Design Inc. All rights reserved. +// Copyright (c) 2023, Cinesite VFX Ltd. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -35,90 +34,15 @@ // ////////////////////////////////////////////////////////////////////////// -/// This file contains the implementation of TypedPlug. Rather than include it -/// in a public header it is #included in TypedPlug.cpp, -/// and the relevant template classes are explicitly instantiated there. This prevents -/// a host of problems to do with the definition of the same symbols in multiple object -/// files. +#pragma once namespace Gaffer { -template -const IECore::RunTimeTyped::TypeDescription > TypedPlug::g_typeDescription; - -template -TypedPlug::TypedPlug( - const std::string &name, - Direction direction, - const T &defaultValue, - unsigned flags -) - : ValuePlug( name, direction, new DataType( defaultValue ), flags ) -{ -} - -template -TypedPlug::~TypedPlug() -{ -} - -template -bool TypedPlug::acceptsInput( const Plug *input ) const -{ - if( !ValuePlug::acceptsInput( input ) ) - { - return false; - } - if( input ) - { - return input->isInstanceOf( staticTypeId() ); - } - return true; -} - -template -PlugPtr TypedPlug::createCounterpart( const std::string &name, Direction direction ) const -{ - return new TypedPlug( name, direction, defaultValue(), getFlags() ); -} - -template -const T &TypedPlug::defaultValue() const -{ - return static_cast( defaultObjectValue() )->readable(); -} - -template -void TypedPlug::setValue( const T &value ) -{ - setObjectValue( new DataType( value ) ); -} - -template -T TypedPlug::getValue( const IECore::MurmurHash *precomputedHash ) const +template +inline T TypedPlug::getValue( const IECore::MurmurHash *precomputedHash ) const { return getObjectValue( precomputedHash )->readable(); } -template -void TypedPlug::setFrom( const ValuePlug *other ) -{ - const TypedPlug *tOther = IECore::runTimeCast >( other ); - if( tOther ) - { - setValue( tOther->getValue() ); - } - else - { - throw IECore::Exception( "Unsupported plug type" ); - } -} - -template -IECore::MurmurHash TypedPlug::hash() const -{ - return ValuePlug::hash(); -} - } // namespace Gaffer diff --git a/include/Gaffer/TypedPlugImplementation.h b/include/Gaffer/TypedPlugImplementation.h new file mode 100644 index 00000000000..f4a37de81b1 --- /dev/null +++ b/include/Gaffer/TypedPlugImplementation.h @@ -0,0 +1,118 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2011-2012, John Haddon. All rights reserved. +// Copyright (c) 2011-2013, 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. +// +////////////////////////////////////////////////////////////////////////// + +/// This file contains the implementation of TypedPlug. Rather than include it +/// in a public header it is #included in TypedPlug.cpp, +/// and the relevant template classes are explicitly instantiated there. This prevents +/// a host of problems to do with the definition of the same symbols in multiple object +/// files. + +namespace Gaffer +{ + +template +const IECore::RunTimeTyped::TypeDescription > TypedPlug::g_typeDescription; + +template +TypedPlug::TypedPlug( + const std::string &name, + Direction direction, + const T &defaultValue, + unsigned flags +) + : ValuePlug( name, direction, new DataType( defaultValue ), flags ) +{ +} + +template +TypedPlug::~TypedPlug() +{ +} + +template +bool TypedPlug::acceptsInput( const Plug *input ) const +{ + if( !ValuePlug::acceptsInput( input ) ) + { + return false; + } + if( input ) + { + return input->isInstanceOf( staticTypeId() ); + } + return true; +} + +template +PlugPtr TypedPlug::createCounterpart( const std::string &name, Direction direction ) const +{ + return new TypedPlug( name, direction, defaultValue(), getFlags() ); +} + +template +const T &TypedPlug::defaultValue() const +{ + return static_cast( defaultObjectValue() )->readable(); +} + +template +void TypedPlug::setValue( const T &value ) +{ + setObjectValue( new DataType( value ) ); +} + +template +void TypedPlug::setFrom( const ValuePlug *other ) +{ + const TypedPlug *tOther = IECore::runTimeCast >( other ); + if( tOther ) + { + setValue( tOther->getValue() ); + } + else + { + throw IECore::Exception( "Unsupported plug type" ); + } +} + +template +IECore::MurmurHash TypedPlug::hash() const +{ + return ValuePlug::hash(); +} + +} // namespace Gaffer diff --git a/include/Gaffer/ValuePlug.inl b/include/Gaffer/ValuePlug.inl index 992c915baf9..8e78d1b0172 100644 --- a/include/Gaffer/ValuePlug.inl +++ b/include/Gaffer/ValuePlug.inl @@ -43,28 +43,18 @@ template boost::intrusive_ptr ValuePlug::getObjectValue( const IECore::MurmurHash *precomputedHash ) const { IECore::ConstObjectPtr value = getValueInternal( precomputedHash ); - boost::intrusive_ptr result = IECore::runTimeCast( value ); - if( !result ) + if( value && value->isInstanceOf( T::staticTypeId() ) ) { - if( !value ) - { - // This is quite a serious error, and it may occur when a calculation has already been cancelled, - // which could result in the exception that first cancelled the calculation being displayed, but - // not this error - print the error as a message as well as throwing an exception - const std::string error = fmt::format( - "{} : getValueInternal() returned NULL. This should be impossible, something has gone badly wrong internally to Gaffer.", - fullName() - ); - IECore::msg( IECore::Msg::Error, "ValuePlug::getObjectValue", error ); - throw IECore::Exception( error ); - } - - throw IECore::Exception( fmt::format( - "{} : getValueInternal() didn't return expected type (wanted {} but got {}). Is the hash being computed correctly?", - fullName(), T::staticTypeName(), value->typeName() - ) ); + // Steal the reference from `value`, to avoid incrementing and decrementing the refcount + // unnecessarily. + /// \todo Add a move-aware variant of `IECore::runTimeCast()` and use it instead. + return boost::intrusive_ptr( static_cast( value.detach() ), /* add_ref = */ false ); } - return result; + + throw IECore::Exception( fmt::format( + "{} : getValueInternal() didn't return expected type (wanted {} but got {}). Is the hash being computed correctly?", + fullName(), T::staticTypeName(), value ? value->typeName() : "nullptr" + ) ); } } // namespace Gaffer diff --git a/include/GafferImage/AtomicFormatPlug.h b/include/GafferImage/AtomicFormatPlug.h index c30b2a780fa..671d558b600 100644 --- a/include/GafferImage/AtomicFormatPlug.h +++ b/include/GafferImage/AtomicFormatPlug.h @@ -49,3 +49,14 @@ using AtomicFormatPlug = Gaffer::TypedPlug; IE_CORE_DECLAREPTR( AtomicFormatPlug ); } // namespace GafferImage + +namespace Gaffer +{ + +template<> +GafferImage::Format GafferImage::AtomicFormatPlug::getValue( const IECore::MurmurHash *precomputedHash ) const; + +template<> +IECore::MurmurHash GafferImage::AtomicFormatPlug::hash() const; + +} // namespace Gaffer diff --git a/src/Gaffer/NumericPlug.cpp b/src/Gaffer/NumericPlug.cpp index 6221b38a9d6..fca2059c8ec 100644 --- a/src/Gaffer/NumericPlug.cpp +++ b/src/Gaffer/NumericPlug.cpp @@ -142,12 +142,6 @@ void NumericPlug::setValue( T value ) setObjectValue( new DataType( value ) ); } -template -T NumericPlug::getValue( const IECore::MurmurHash *precomputedHash ) const -{ - return getObjectValue( precomputedHash )->readable(); -} - template void NumericPlug::setFrom( const ValuePlug *other ) { diff --git a/src/Gaffer/Plug.cpp b/src/Gaffer/Plug.cpp index 2523f18d5de..5de181e1cdd 100644 --- a/src/Gaffer/Plug.cpp +++ b/src/Gaffer/Plug.cpp @@ -136,21 +136,6 @@ bool Plug::acceptsParent( const GraphComponent *potentialParent ) const return potentialParent->isInstanceOf( (IECore::TypeId)NodeTypeId ) || potentialParent->isInstanceOf( Plug::staticTypeId() ); } -Node *Plug::node() -{ - return ancestor(); -} - -const Node *Plug::node() const -{ - return ancestor(); -} - -Plug::Direction Plug::direction() const -{ - return m_direction; -} - unsigned Plug::getFlags() const { return m_flags; diff --git a/src/Gaffer/TypedObjectPlug.cpp b/src/Gaffer/TypedObjectPlug.cpp index 54ebe3b00c2..7cf2a8b78d2 100644 --- a/src/Gaffer/TypedObjectPlug.cpp +++ b/src/Gaffer/TypedObjectPlug.cpp @@ -38,7 +38,7 @@ #include "Gaffer/TypedObjectPlug.h" #include "Gaffer/StringPlug.h" -#include "Gaffer/TypedObjectPlug.inl" +#include "Gaffer/TypedObjectPlugImplementation.h" #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" diff --git a/src/Gaffer/TypedPlug.cpp b/src/Gaffer/TypedPlug.cpp index c6080c33050..1377c843990 100644 --- a/src/Gaffer/TypedPlug.cpp +++ b/src/Gaffer/TypedPlug.cpp @@ -39,7 +39,7 @@ #include "Gaffer/NumericPlug.h" #include "Gaffer/StringPlug.h" -#include "Gaffer/TypedPlug.inl" +#include "Gaffer/TypedPlugImplementation.h" namespace Gaffer { diff --git a/src/Gaffer/ValuePlug.cpp b/src/Gaffer/ValuePlug.cpp index bb87f9ce033..809968ffe89 100644 --- a/src/Gaffer/ValuePlug.cpp +++ b/src/Gaffer/ValuePlug.cpp @@ -69,9 +69,13 @@ namespace /// and avoids the creation of lots of unnecessary cache entries. inline const ValuePlug *sourcePlug( const ValuePlug *p ) { - const IECore::TypeId typeId = p->typeId(); - const ValuePlug *in = p->getInput(); + if( !in ) + { + return p; + } + + const IECore::TypeId typeId = p->typeId(); while( in && in->typeId() == typeId ) { p = in; @@ -641,7 +645,8 @@ class ValuePlug::ComputeProcess : public Process // the same item from the cache, leading to deadlock. if( auto result = g_cache.getIfCached( processKey ) ) { - return *result; + // Move avoids unnecessary additional addRef/removeRef. + return std::move( *result ); } ComputeProcess process( processKey ); // Store the value in the cache, but only if it isn't there diff --git a/src/GafferImage/AtomicFormatPlug.cpp b/src/GafferImage/AtomicFormatPlug.cpp index ff1d78c2f21..3ef6693e1c8 100644 --- a/src/GafferImage/AtomicFormatPlug.cpp +++ b/src/GafferImage/AtomicFormatPlug.cpp @@ -42,7 +42,7 @@ #include "Gaffer/Context.h" #include "Gaffer/Process.h" #include "Gaffer/TypedPlug.h" -#include "Gaffer/TypedPlug.inl" +#include "Gaffer/TypedPlugImplementation.h" using namespace Gaffer; using namespace GafferImage;