Skip to content

Commit

Permalink
Merge pull request #3513 from Autodesk/bailp/EMSUSD-65/load-payload-w…
Browse files Browse the repository at this point in the history
…ait-cursor

EMSUSD-65 use wait cursor for payload commands
  • Loading branch information
seando-adsk authored Dec 14, 2023
2 parents 1a83777 + 69ef548 commit c16e588
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 10 deletions.
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"); }

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
7 changes: 0 additions & 7 deletions lib/mayaUsd/ufe/MayaUsdContextOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,6 @@ static constexpr char kAddRefOrPayloadItem[] = "AddReferenceOrPayload";
const constexpr char kClearAllRefsOrPayloadsLabel[] = "Clear All USD References/Payloads...";
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

0 comments on commit c16e588

Please sign in to comment.