-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash when creating an ImageWriter #681
Comments
I've done a bit of investigation into this one, and it transpires that the crash is occurring when auto-connecting Constant.out to ImageWriter.requirements. I think this is because the requirements ArrayPlug is adding children while the CompoundPlug base class is connecting them. This connection should never be allowed to be attempted in the first place though, because we really only want requirements plugs to accept connections from the requirement output of another Executable node. To prevent that we'd need to implement ExecutableNode::acceptsInput() to reject the connection, but that seems wrong - we don't want to have to reimplement the same thing in every type that inherits Executable. Maybe Executable can implement it itself, and it'll work when it gets multiply-inherited into ExecutableNode? Or maybe we really don't need the whole multiple-inheritance of the Executable class and could just have ExecutableNode? |
Just to clarify my previous comments a bit. There is a very easy fix for this - implement ImageWriter::acceptsInput() to take into account Executable::acceptsRequirementsInput() in the same way that ExecutableOpHolder does. If anyone wants the fix quickly I'll be more than happy to do it, but otherwise I'm going to leave this here as a thorn in my side while I think about rejigging Executable/ExecutableNode so there's less burden on subclass implementers to get things right. |
This one is my bad. I knew that this was an issue but it slipped through the cracks when I wrote the writer. I like the idea of having the base class hadle it though. |
Cool. I'm definitely leaning towards having the base class simply be ExecutableNode, and removing the Executable abstract class. That would sit nicely alongside ComputeNode and DependencyNode as three sensible base classes for different circumstances that all operate along similar lines. If we do that we can remove the burden from the subclass implementers and we'll have a more straightforward class hierarchy as well. |
That sounds good to me. Nice and clean. |
Addressed in #782 - closing. |
I originally suggested to Lucio that he develop the Executable nodes using multiple inheritance of an Executable interface class, so that nodes could be both say a SceneNode and also Executable. That turned out to be a bad idea because the class hierarchy was rather confusing and it put the onus on developers to remember to call various methods to add plugs, test inputs were accepted etc. This led to problems like the crash bug in GafferHQ#681, and was just generally a bit more awkward than necessary. This commit simplifies things so there is now just a single ExecutableNode base class which fits in nicely with the DependencyNode and ComputeNode base classes. The implementations for the various derived classes are now a fair bit simpler, and the bindings are performed with a new ExecutableNodeClass which matches nicely with the NodeClass and DependencyNodeClass we already have.
I originally suggested to Lucio that he develop the Executable nodes using multiple inheritance of an Executable interface class, so that nodes could be both say a SceneNode and also Executable. That turned out to be a bad idea because the class hierarchy was rather confusing and it put the onus on developers to remember to call various methods to add plugs, test inputs were accepted etc. This led to problems like the crash bug in GafferHQ#681, and was just generally a bit more awkward than necessary. This commit simplifies things so there is now just a single ExecutableNode base class which fits in nicely with the DependencyNode and ComputeNode base classes. The implementations for the various derived classes are now a fair bit simpler, and the bindings are performed with a new ExecutableNodeClass which matches nicely with the NodeClass and DependencyNodeClass we already have.
1 libGaffer.dylib 0x0000000105dc271b Gaffer::CompoundPlug::setInput(IECore::IntrusivePtrGaffer::Plug) + 673
2 libGafferUI.dylib 0x0000000106d5ebde GafferUI::StandardGraphLayout::connectNodeInternal(GafferUI::GraphGadget_, Gaffer::Node_, Gaffer::Set_, bool) const + 300
3 libGafferUI.dylib 0x0000000106d5f1a5 GafferUI::StandardGraphLayout::connectNode(GafferUI::GraphGadget_, Gaffer::Node_, Gaffer::Set_) const + 15
4 libGafferUIBindings.dylib 0x0000000106e7c65e boost::python::detail::caller_arity<4u>::impl<bool (GafferUI::GraphLayout::)(GafferUI::GraphGadget, Gaffer::Node*, Gaffer::Set*) const, boost::python::default_call_policies, boost::mpl::vector5<bool, GafferUI::GraphLayout&, GafferUI::GraphGadget*, Gaffer::Node*, Gaffer::Set*> >::operator()(object, object) + 258
5 libboost_python.dylib 0x000000010074bd73 boost::python::objects::function::call(object, object) const + 733 (function.cpp:234)
6 libboost_python.dylib 0x000000010074a950 boost::detail::function::void_function_ref_invoker0<boost::python::objects::(anonymous namespace)::bind_return, void>::invoke(boost::detail::function::function_buffer&) + 32 (function.cpp:585)
7 libboost_python.dylib 0x0000000100753a2c boost::python::detail::exception_handler::operator()(boost::function0 const&) const + 174 (function_template.hpp:1013)
8 libIECorePython.dylib 0x00000001023ab094 bool boost::_bi::list3boost::arg<1, boost::arg<2>, boost::_bi::value<void ()(IECore::Exception const&)> >::operator()<bool, boost::python::detail::translate_exception<IECore::Exception, void ()(IECore::Exception const&)>, boost::_bi::list2<boost::python::detail::exception_handler const&, boost::function0 const&> >(boost::_bi::type, boost::python::detail::translate_exception<IECore::Exception, void ()(IECore::Exception const&)>&, boost::_bi::list2<boost::python::detail::exception_handler const&, boost::function0 const&>&, long) + 24
9 libIECorePython.dylib 0x00000001023aaf8b boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool, boost::python::detail::translate_exception<IECore::Exception, void ()(IECore::Exception const&)>, boost::_bi::list3boost::arg<1, boost::arg<2>, boost::_bi::value<void (*)(IECore::Exception const&)> > >, bool, boost::python::detail::exception_handler const&, boost::function0 const&>::invoke(boost::detail::function::function_buffer&, boost::python::detail::exception_handler const&, boost::function0 const&) + 43
10 libboost_python.dylib 0x0000000100753a93 boost::python::handle_exception_impl(boost::function0) + 99 (function_template.hpp:1013)
11 libboost_python.dylib 0x000000010074ae2f function_call + 79 (function_template.hpp:752)
The text was updated successfully, but these errors were encountered: