Skip to content

Commit

Permalink
Merge pull request #3856 from Autodesk/bailp/EMSUSD-1361/python-edit-…
Browse files Browse the repository at this point in the history
…router-crash

EMSUSD-1361 Same-name Python edit routers
  • Loading branch information
seando-adsk authored Jul 17, 2024
2 parents 6fe44cb + 8f46e51 commit bc3bd84
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/mayaUsd/python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from usdUfe import registerStageLayerEditRouter
from usdUfe import restoreDefaultEditRouter
from usdUfe import restoreAllDefaultEditRouters
from usdUfe import clearAllEditRouters
from usdUfe import OperationEditRouterContext
from usdUfe import AttributeEditRouterContext
from usdUfe import registerUICallback
Expand Down
2 changes: 2 additions & 0 deletions lib/mayaUsd/ufe/Global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ MStatus finalize(bool exiting)
g_MayaUIInfoHandler.reset();
#endif

UsdUfe::clearAllEditRouters();

MMessage::removeCallback(gExitingCbId);

return MS::kSuccess;
Expand Down
11 changes: 10 additions & 1 deletion lib/usdUfe/python/wrapEditRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,16 @@ class PyEditRouter : public UsdUfe::EditRouter
PyEditRouter(PyObject* pyCallable)
: _pyCb(pyCallable)
{
if (_pyCb)
Py_INCREF(_pyCb);
}

~PyEditRouter() override { }
~PyEditRouter() override
{
PXR_NS::TfPyLock pyLock;
if (_pyCb)
Py_DECREF(_pyCb);
}

void operator()(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionary& routingData) override
{
Expand Down Expand Up @@ -182,6 +189,8 @@ void wrapEditRouter()

def("restoreAllDefaultEditRouters", &UsdUfe::restoreAllDefaultEditRouters);

def("clearAllEditRouters", &UsdUfe::clearAllEditRouters);

using OpThis = UsdUfe::OperationEditRouterContext;
class_<OpThis, boost::noncopyable>("OperationEditRouterContext", no_init)
.def("__init__", make_constructor(OperationEditRouterContextInit));
Expand Down
4 changes: 3 additions & 1 deletion lib/usdUfe/utils/editRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,11 @@ bool restoreDefaultEditRouter(const PXR_NS::TfToken& operation)
return true;
}

void clearAllEditRouters() { getRegisteredEditRouters().clear(); }

void restoreAllDefaultEditRouters()
{
getRegisteredEditRouters().clear();
clearAllEditRouters();

auto defaults = defaultEditRouters();
for (const auto& entry : defaults) {
Expand Down
6 changes: 6 additions & 0 deletions lib/usdUfe/utils/editRouter.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ void restoreAllDefaultEditRouters();
USDUFE_PUBLIC
void registerDefaultEditRouter(const PXR_NS::TfToken&, const EditRouter::Ptr&);

// Clear all registered edit routers.
// Mostly only used on exit to ensure edit routers are cleared to avoid order of destruction
// problems.
USDUFE_PUBLIC
void clearAllEditRouters();

// Return built-in default edit routers.
EditRouters defaultEditRouters();

Expand Down
32 changes: 32 additions & 0 deletions test/lib/ufe/testEditRouting.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def setUp(self):

def tearDown(self):
# Restore default edit routers.
mayaUsd.lib.clearAllEditRouters()
mayaUsd.lib.restoreAllDefaultEditRouters()

def _prepareSimpleScene(self):
Expand Down Expand Up @@ -687,7 +688,38 @@ def Xform "B"
'''
self.maxDiff = None
self.assertEqual(filterUsdStr(self.sessionLayer.ExportToString()), filterUsdStr(expectedContents))

def testRegisterLambdaEditRouter(self):
'''
Test registering lambda function and forgetiing bout it.
This test that the edit router system properly keeps a reference
on the given router.
'''
self._prepareSimpleScene()

# Regsiter a lambda as the edit router:

router = lambda context, routingData: routingData.update(
{'layer': context.get('prim').GetStage().GetSessionLayer().identifier})
mayaUsd.lib.registerEditRouter('visibility', router)
router = None

def setVisibility():
cmds.hide()

def verifyVisibility(sessionLayer):
self.assertIsNotNone(sessionLayer.GetPrimAtPath('/B'))

# Check that any visibility changes were written to the session layer
self.assertIsNotNone(sessionLayer.GetAttributeAtPath('/B.visibility').default)

# Check that correct visibility changes were written to the session layer
self.assertEqual(filterUsdStr(sessionLayer.ExportToString()),
filterUsdStr('over "B"\n{\n token visibility = "invisible"\n}'))

setVisibility()
verifyVisibility(self.sessionLayer)


if __name__ == '__main__':
unittest.main(verbosity=2)

0 comments on commit bc3bd84

Please sign in to comment.