Files
PrimeWorldEditor/src/Editor/Undo/CDeleteLinksCommand.cpp
Lioncache 2f45cfd06a CDeleteLinksCommand: Move struct to internal implementation
Allows ease of extending, etc without cascading rebuilds.
2025-12-16 22:50:31 -05:00

116 lines
3.3 KiB
C++

#include "Editor/Undo/CDeleteLinksCommand.h"
#include "Editor/WorldEditor/CWorldEditor.h"
#include <Core/Resource/Script/CLink.h>
#include <QCoreApplication>
struct CDeleteLinksCommand::SDeletedLink
{
uint32 State;
uint32 Message;
CInstancePtr pSender;
CInstancePtr pReceiver;
uint32 SenderIndex;
uint32 ReceiverIndex;
};
CDeleteLinksCommand::CDeleteLinksCommand() = default;
CDeleteLinksCommand::CDeleteLinksCommand(CWorldEditor *pEditor, CScriptObject *pObject, ELinkType Type, const QList<uint32>& rkIndices)
: IUndoCommand(QCoreApplication::translate("CDeleteLinksCommand", "Delete Links"))
, mpEditor(pEditor)
{
mAffectedInstances.push_back(pObject);
for (const auto index : rkIndices)
{
const CLink *pLink = pObject->Link(Type, index);
mLinks.push_back({
.State = pLink->State(),
.Message = pLink->Message(),
.pSender = pLink->Sender(),
.pReceiver = pLink->Receiver(),
.SenderIndex = pLink->SenderIndex(),
.ReceiverIndex = pLink->ReceiverIndex(),
});
const auto& DelLink = mLinks.back();
if (Type == ELinkType::Outgoing)
{
if (!mAffectedInstances.contains(DelLink.pReceiver))
mAffectedInstances.push_back(DelLink.pReceiver);
}
else
{
if (!mAffectedInstances.contains(DelLink.pSender))
mAffectedInstances.push_back(DelLink.pSender);
}
}
}
CDeleteLinksCommand::~CDeleteLinksCommand() = default;
void CDeleteLinksCommand::undo()
{
struct SNewLink
{
SDeletedLink *pDelLink;
CLink *pLink;
static bool SenderIndexSorter(const SNewLink& l, const SNewLink& r) {
return l.pDelLink->SenderIndex < r.pDelLink->SenderIndex;
}
static bool ReceiverIndexSorter(const SNewLink& l, const SNewLink& r) {
return l.pDelLink->ReceiverIndex < r.pDelLink->ReceiverIndex;
}
};
QList<SNewLink> NewLinks;
for (SDeletedLink& rDelLink : mLinks)
{
NewLinks.push_back({
.pDelLink = &rDelLink,
.pLink = new CLink(mpEditor->ActiveArea(), rDelLink.State, rDelLink.Message, rDelLink.pSender.InstanceID(), rDelLink.pReceiver.InstanceID()),
});
}
// Add to senders
std::sort(NewLinks.begin(), NewLinks.end(), &SNewLink::SenderIndexSorter);
for (SNewLink& rNew : NewLinks)
{
rNew.pDelLink->pSender->AddLink(ELinkType::Outgoing, rNew.pLink, rNew.pDelLink->SenderIndex);
}
// Add to receivers
std::sort(NewLinks.begin(), NewLinks.end(), &SNewLink::ReceiverIndexSorter);
for (SNewLink& rNew : NewLinks)
{
rNew.pDelLink->pReceiver->AddLink(ELinkType::Incoming, rNew.pLink, rNew.pDelLink->ReceiverIndex);
}
// Notify world editor
mpEditor->OnLinksModified(mAffectedInstances.DereferenceList());
}
void CDeleteLinksCommand::redo()
{
QList<CLink*> Links;
for (const auto& rLink : mLinks)
{
Links.push_back(rLink.pSender->Link(ELinkType::Outgoing, rLink.SenderIndex));
}
for (auto* pLink : Links)
{
pLink->Sender()->RemoveLink(ELinkType::Outgoing, pLink);
pLink->Receiver()->RemoveLink(ELinkType::Incoming, pLink);
delete pLink;
}
// Notify world editor
mpEditor->OnLinksModified(mAffectedInstances.DereferenceList());
}