Skip to content
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

EMSUSD-65 use wait cursor for payload commands #3513

Merged
merged 2 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/mayaUsd/ufe/Global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
#include <usdUfe/ufe/UfeVersionCompat.h>
#include <usdUfe/utils/editRouter.h>

#include <maya/MGlobal.h>
#include <maya/MSceneMessage.h>
#include <ufe/hierarchyHandler.h>
#include <ufe/pathString.h>
Expand Down Expand Up @@ -107,6 +108,10 @@ MCallbackId gExitingCbId = 0;
// Subject singleton for observation of all USD stages.
MayaUsd::ufe::MayaStagesSubject::RefPtr g_StagesSubject;

void mayaStartWaitCursor() { MGlobal::executeCommand("waitCursor -state 1"); }
Copy link
Collaborator

@AramAzhari-adsk AramAzhari-adsk Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like something that should be in usdUfe/Utils and not Global, as this isn't manipulating or using anything Ufe and I think it is going to be useful for the rest of MayaUsd.

Copy link
Collaborator Author

@pierrebai-adsk pierrebai-adsk Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other code can use the usdUfe API, not this implementation. Particularly since the code in usdUfe manages the recursivity count and provide a utility WaitCursor class.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mayaUsd has access to usdUfe but probably not the other way around.

I also noticed that you've removed the struct in MayaUsdContextOps.

Copy link
Collaborator

@seando-adsk seando-adsk Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particular code cannot be in UsdUfe since it uses Maya. UsdUfe does not (and cannot) depend on Maya. The way that Pierre wrapped it behind dccFunctions is the correct thing to do.


void mayaStopWaitCursor() { MGlobal::executeCommand("waitCursor -state 0"); }

} // namespace

namespace MAYAUSD_NS_DEF {
Expand Down Expand Up @@ -165,6 +170,8 @@ MStatus initialize()
dccFunctions.isAttributeLockedFn = MayaUsd::Editability::isAttributeLocked;
dccFunctions.saveStageLoadRulesFn = MayaUsd::MayaUsdProxyShapeStageExtraData::saveLoadRules;
dccFunctions.uniqueChildNameFn = MayaUsd::ufe::uniqueChildNameMayaStandard;
dccFunctions.startWaitCursorFn = mayaStartWaitCursor;
dccFunctions.stopWaitCursorFn = mayaStopWaitCursor;

// Replace the Maya hierarchy handler with ours.
auto& runTimeMgr = Ufe::RunTimeMgr::instance();
Expand Down
6 changes: 0 additions & 6 deletions lib/mayaUsd/ufe/MayaUsdContextOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,6 @@ const constexpr char kClearAllRefsOrPayloadsLabel[] = "Clear All USD References
const constexpr char kClearAllRefsOrPayloadsItem[] = "ClearAllReferencesOrPayloads";

//! \brief Change the cursor to wait state on construction and restore it on destruction.
struct WaitCursor
{
WaitCursor() { MGlobal::executeCommand("waitCursor -state 1"); }
~WaitCursor() { MGlobal::executeCommand("waitCursor -state 0"); }
};

#ifdef UFE_V3_FEATURES_AVAILABLE
//! \brief Create a working Material and select it:
class InsertChildAndSelectCommand : public Ufe::CompositeUndoableCommand
Expand Down
2 changes: 2 additions & 0 deletions lib/usdUfe/ufe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ target_sources(${PROJECT_NAME}
UsdUndoClearReferencesCommand.cpp
UsdUndoCreateGroupCommand.cpp
UsdUndoInsertChildCommand.cpp
UsdUndoLongDurationCommand.cpp
UsdUndoPayloadCommand.cpp
UsdUndoReorderCommand.cpp
UsdUndoSelectAfterCommand.cpp
Expand Down Expand Up @@ -78,6 +79,7 @@ set(HEADERS
UsdUndoClearReferencesCommand.h
UsdUndoCreateGroupCommand.h
UsdUndoInsertChildCommand.h
UsdUndoLongDurationCommand.h
UsdUndoPayloadCommand.h
UsdUndoReorderCommand.h
UsdUndoSelectAfterCommand.h
Expand Down
1 change: 1 addition & 0 deletions lib/usdUfe/ufe/Global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Ufe::Rtid initialize(
UsdUfe::setStagePathAccessorFn(dccFunctions.stagePathAccessorFn);
UsdUfe::setUfePathToPrimFn(dccFunctions.ufePathToPrimFn);
UsdUfe::setTimeAccessorFn(dccFunctions.timeAccessorFn);
UsdUfe::setWaitCursorFns(dccFunctions.startWaitCursorFn, dccFunctions.stopWaitCursorFn);

// Optional DCC specific functions.
if (dccFunctions.isAttributeLockedFn)
Expand Down
4 changes: 4 additions & 0 deletions lib/usdUfe/ufe/Global.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ struct USDUFE_PUBLIC DCCFunctions
SaveStageLoadRulesFn saveStageLoadRulesFn = nullptr;
IsRootChildFn isRootChildFn = nullptr;
UniqueChildNameFn uniqueChildNameFn = nullptr;

// Optional: nothing will be done if no function is supplied.
WaitCursorFn startWaitCursorFn = nullptr;
WaitCursorFn stopWaitCursorFn = nullptr;
};

/*! Ufe runtime handlers used to initialize the plugin.
Expand Down
8 changes: 5 additions & 3 deletions lib/usdUfe/ufe/UsdContextOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <usdUfe/ufe/UsdSceneItem.h>
#include <usdUfe/ufe/UsdUndoAddNewPrimCommand.h>
#include <usdUfe/ufe/UsdUndoClearDefaultPrimCommand.h>
#include <usdUfe/ufe/UsdUndoLongDurationCommand.h>
#include <usdUfe/ufe/UsdUndoPayloadCommand.h>
#include <usdUfe/ufe/UsdUndoSelectAfterCommand.h>
#include <usdUfe/ufe/UsdUndoSetDefaultPrimCommand.h>
Expand Down Expand Up @@ -542,10 +543,11 @@ Ufe::UndoableCommand::Ptr UsdContextOps::doOpCmd(const ItemPath& itemPath)
const UsdLoadPolicy policy = (itemPath[0u] == kUSDLoadWithDescendantsItem)
? UsdLoadWithDescendants
: UsdLoadWithoutDescendants;

return std::make_shared<UsdUndoLoadPayloadCommand>(prim(), policy);
return UsdUndoLongDurationCommand::create(
{ std::make_shared<UsdUndoLoadPayloadCommand>(prim(), policy) });
} else if (itemPath[0u] == kUSDUnloadItem) {
return std::make_shared<UsdUndoUnloadPayloadCommand>(prim());
return UsdUndoLongDurationCommand::create(
{ std::make_shared<UsdUndoUnloadPayloadCommand>(prim()) });
} else if (itemPath[0] == kUSDVariantSetsItem) {
// Operation is to set a variant in a variant set. Need both the
// variant set and the variant as arguments to the operation.
Expand Down
61 changes: 61 additions & 0 deletions lib/usdUfe/ufe/UsdUndoLongDurationCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// Copyright 2023 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "UsdUndoLongDurationCommand.h"

#include <usdUfe/ufe/Utils.h>

namespace USDUFE_NS_DEF {

/* static */ std::shared_ptr<UsdUndoLongDurationCommand>
UsdUndoLongDurationCommand::create(std::initializer_list<Ptr> undoableCommands)
{
return std::make_shared<UsdUndoLongDurationCommand>(undoableCommands);
}

UsdUndoLongDurationCommand::UsdUndoLongDurationCommand() = default;

UsdUndoLongDurationCommand::UsdUndoLongDurationCommand(std::initializer_list<Ptr> undoableCommands)
: Parent(undoableCommands)
{
}

UsdUndoLongDurationCommand::UsdUndoLongDurationCommand(const std::list<Ptr>& undoableCommands)
: Parent(undoableCommands)
{
}

UsdUndoLongDurationCommand::~UsdUndoLongDurationCommand() = default;

void UsdUndoLongDurationCommand::execute()
{
WaitCursor waitCursor;
Parent::execute();
}

void UsdUndoLongDurationCommand::undo()
{
WaitCursor waitCursor;
Parent::undo();
}

void UsdUndoLongDurationCommand::redo()
{
WaitCursor waitCursor;
Parent::redo();
}

}; // namespace USDUFE_NS_DEF
57 changes: 57 additions & 0 deletions lib/usdUfe/ufe/UsdUndoLongDurationCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Copyright 2023 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#pragma once

#include <usdUfe/base/api.h>

#include <ufe/undoableCommand.h>

namespace USDUFE_NS_DEF {

//! \brief UsdUndoLongDurationCommand
//
// A composite command that wraps all sub-commands within a user-visible wait cursor.
class USDUFE_PUBLIC UsdUndoLongDurationCommand : public Ufe::CompositeUndoableCommand
{
public:
using Parent = Ufe::CompositeUndoableCommand;

//! Create the long-duration composite command and append the argument commands to it.
//! \return Pointer to the long-duration composite undoable command.
static std::shared_ptr<UsdUndoLongDurationCommand>
create(std::initializer_list<Ptr> undoableCommands);

//@{
//! Constructors.
UsdUndoLongDurationCommand();
UsdUndoLongDurationCommand(std::initializer_list<Ptr> undoableCommands);
UsdUndoLongDurationCommand(const std::list<Ptr>& undoableCommands);

//@}
//! Destructor.
~UsdUndoLongDurationCommand() override;

//! Calls execute() on each command in the list, in forward order.
void execute() override;

//! Calls undo() on each command in the list, in reverse order.
void undo() override;

//! Calls redo() on each command in the list, in forward order.
void redo() override;
};

} // namespace USDUFE_NS_DEF
32 changes: 32 additions & 0 deletions lib/usdUfe/ufe/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ uint32_t findLayerIndex(const UsdPrim& prim, const SdfLayerHandle& layer)
return position;
}

int gWaitCursorCount = 0;

UsdUfe::StageAccessorFn gStageAccessorFn = nullptr;
UsdUfe::StagePathAccessorFn gStagePathAccessorFn = nullptr;
UsdUfe::UfePathToPrimFn gUfePathToPrimFn = nullptr;
Expand All @@ -95,6 +97,8 @@ UsdUfe::IsAttributeLockedFn gIsAttributeLockedFn = nullptr;
UsdUfe::SaveStageLoadRulesFn gSaveStageLoadRulesFn = nullptr;
UsdUfe::IsRootChildFn gIsRootChildFn = nullptr;
UsdUfe::UniqueChildNameFn gUniqueChildNameFn = nullptr;
UsdUfe::WaitCursorFn gStartWaitCursorFn = nullptr;
UsdUfe::WaitCursorFn gStopWaitCursorFn = nullptr;

} // anonymous namespace

Expand Down Expand Up @@ -914,4 +918,32 @@ Ufe::Value vtValueToUfeValue(const PXR_NS::VtValue& vtValue)
}
#endif

void setWaitCursorFns(WaitCursorFn startFn, WaitCursorFn stopFn)
{
gStartWaitCursorFn = startFn;
gStopWaitCursorFn = stopFn;
}

void startWaitCursor()
{
if (!gStartWaitCursorFn)
return;

if (gWaitCursorCount == 0)
gStartWaitCursorFn();

++gWaitCursorCount;
}

void stopWaitCursor()
{
if (!gStopWaitCursorFn)
return;

--gWaitCursorCount;

if (gWaitCursorCount == 0)
gStopWaitCursorFn();
}

} // namespace USDUFE_NS_DEF
20 changes: 20 additions & 0 deletions lib/usdUfe/ufe/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef bool (*IsAttributeLockedFn)(const PXR_NS::UsdAttribute& attr, std::strin
typedef void (*SaveStageLoadRulesFn)(const PXR_NS::UsdStageRefPtr&);
typedef bool (*IsRootChildFn)(const Ufe::Path& path);
typedef std::string (*UniqueChildNameFn)(const PXR_NS::UsdPrim& usdParent, const std::string& name);
typedef void (*WaitCursorFn)();

//------------------------------------------------------------------------------
// Helper functions
Expand Down Expand Up @@ -299,4 +300,23 @@ bool isEditTargetLayerModifiable(
USDUFE_PUBLIC
Ufe::BBox3d combineUfeBBox(const Ufe::BBox3d& ufeBBox1, const Ufe::BBox3d& ufeBBox2);

//! Set both the start and stop wait cursor functions.
USDUFE_PUBLIC
void setWaitCursorFns(WaitCursorFn startFn, WaitCursorFn stopFn);

//! Start the wait cursor. Can be called recursively.
USDUFE_PUBLIC
void startWaitCursor();

//! Stop the wait cursor. Can be called recursively.
USDUFE_PUBLIC
void stopWaitCursor();

//! Start and stop the wait cursor in the constructor and destructor.
struct USDUFE_PUBLIC WaitCursor
{
WaitCursor() { startWaitCursor(); }
~WaitCursor() { stopWaitCursor(); }
};

} // namespace USDUFE_NS_DEF