metaforce/Runtime/CIOWinManager.cpp

293 lines
7.7 KiB
C++
Raw Normal View History

2015-08-19 19:52:07 -07:00
#include "CIOWinManager.hpp"
2015-08-21 18:58:41 -07:00
#include "CArchitectureMessage.hpp"
2015-08-28 18:30:47 -07:00
#include "CIOWin.hpp"
2015-08-19 19:52:07 -07:00
2016-03-04 15:04:53 -08:00
namespace urde
2015-08-19 19:52:07 -07:00
{
bool CIOWinManager::OnIOWinMessage(const CArchitectureMessage& msg)
{
switch (msg.GetType())
{
2015-11-20 17:16:07 -08:00
case EArchMsgType::RemoveIOWin:
2015-08-25 18:34:56 -07:00
{
const CArchMsgParmVoidPtr& parm = MakeMsg::GetParmDeleteIOWin(msg);
CIOWin* iow = FindIOWin(*static_cast<const std::string*>(parm.x4_parm1));
2015-08-25 18:34:56 -07:00
if (iow)
RemoveIOWin(iow);
return false;
}
2015-11-20 17:16:07 -08:00
case EArchMsgType::CreateIOWin:
2015-08-25 18:34:56 -07:00
{
const CArchMsgParmInt32Int32IOWin& parm = MakeMsg::GetParmCreateIOWin(msg);
AddIOWin(parm.xc_parm3, parm.x4_parm1, parm.x8_parm2);
2015-08-25 18:34:56 -07:00
return false;
}
2015-11-20 17:16:07 -08:00
case EArchMsgType::ChangeIOWinPriority:
2015-08-19 19:52:07 -07:00
{
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmChangeIOWinPriority(msg);
CIOWin* iow = FindIOWin(*static_cast<const std::string*>(parm.xc_parm3));
2015-08-25 18:34:56 -07:00
if (iow)
ChangeIOWinPriority(iow, parm.x4_parm1, parm.x8_parm2);
return false;
}
2015-11-20 17:16:07 -08:00
case EArchMsgType::RemoveAllIOWins:
2015-08-25 18:34:56 -07:00
{
RemoveAllIOWins();
return true;
2015-08-19 19:52:07 -07:00
}
default: break;
}
return false;
}
2015-08-25 18:34:56 -07:00
void CIOWinManager::Draw() const
{
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x0_drawRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
2015-08-25 18:34:56 -07:00
iow->PreDraw();
if (!iow->GetIsContinueDraw())
break;
}
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x0_drawRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
2015-08-25 18:34:56 -07:00
iow->Draw();
if (!iow->GetIsContinueDraw())
break;
}
}
bool CIOWinManager::DistributeOneMessage(const CArchitectureMessage& msg,
CArchitectureQueue& queue)
{
CArchitectureMessage tmpMsg = msg;
2017-02-05 19:21:58 -08:00
for (IOWinPQNode* node = x4_pumpRoot ; node ;)
2015-08-25 18:34:56 -07:00
{
2017-02-05 19:21:58 -08:00
IOWinPQNode* next = node->x8_next;
CIOWin* iow = node->GetIOWin();
CIOWin::EMessageReturn mret = iow->OnMessage(tmpMsg, x8_localGatherQueue);
2015-08-25 18:34:56 -07:00
2015-08-26 17:23:46 -07:00
while (x8_localGatherQueue)
2015-08-25 18:34:56 -07:00
{
tmpMsg = x8_localGatherQueue.Pop();
if (tmpMsg.GetTarget() == EArchMsgTarget::IOWinManager)
2015-08-25 18:34:56 -07:00
{
if (OnIOWinMessage(tmpMsg))
2015-08-25 18:34:56 -07:00
{
2015-08-26 17:23:46 -07:00
x8_localGatherQueue.Clear();
2015-08-25 18:34:56 -07:00
queue.Clear();
return true;
}
}
else
queue.Push(std::move(tmpMsg));
2015-08-25 18:34:56 -07:00
}
switch (mret)
{
2015-11-20 17:16:07 -08:00
case CIOWin::EMessageReturn::RemoveIOWinAndExit:
case CIOWin::EMessageReturn::RemoveIOWin:
2015-08-25 18:34:56 -07:00
RemoveIOWin(iow);
default: break;
}
switch (mret)
{
2015-11-20 17:16:07 -08:00
case CIOWin::EMessageReturn::Exit:
case CIOWin::EMessageReturn::RemoveIOWinAndExit:
2015-08-25 18:34:56 -07:00
return false;
default: break;
}
2017-02-05 19:21:58 -08:00
node = next;
2015-08-25 18:34:56 -07:00
}
return false;
}
void CIOWinManager::PumpMessages(CArchitectureQueue& queue)
{
while (queue)
{
CArchitectureMessage msg = queue.Pop();
if (DistributeOneMessage(msg, queue))
break;
}
}
2017-11-12 22:19:18 -08:00
CIOWin* CIOWinManager::FindIOWin(std::string_view name)
2015-08-25 18:34:56 -07:00
{
2017-11-12 22:19:18 -08:00
size_t findHash = std::hash<std::string_view>()(name);
2015-08-25 18:34:56 -07:00
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x4_pumpRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
2015-08-25 18:34:56 -07:00
if (iow->GetNameHash() == findHash)
return iow;
}
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x0_drawRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
if (iow->GetNameHash() == findHash)
return iow;
}
return nullptr;
}
2017-11-12 22:19:18 -08:00
std::shared_ptr<CIOWin> CIOWinManager::FindAndShareIOWin(std::string_view name)
{
2017-11-12 22:19:18 -08:00
size_t findHash = std::hash<std::string_view>()(name);
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x4_pumpRoot ; node ; node = node->x8_next)
{
std::shared_ptr<CIOWin> iow = node->ShareIOWin();
if (iow->GetNameHash() == findHash)
return iow;
}
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x0_drawRoot ; node ; node = node->x8_next)
{
std::shared_ptr<CIOWin> iow = node->ShareIOWin();
2015-08-25 18:34:56 -07:00
if (iow->GetNameHash() == findHash)
return iow;
}
return std::shared_ptr<CIOWin>();
2015-08-25 18:34:56 -07:00
}
void CIOWinManager::ChangeIOWinPriority(CIOWin* toChange, int pumpPrio, int drawPrio)
2015-08-25 18:34:56 -07:00
{
IOWinPQNode* prevNode = nullptr;
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x4_pumpRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
if (iow == toChange)
2015-08-25 18:34:56 -07:00
{
if (prevNode)
prevNode->x8_next = node->x8_next;
node->x4_prio = pumpPrio;
IOWinPQNode* testNode = x4_pumpRoot;
IOWinPQNode* testPrevNode = nullptr;
2015-08-25 18:34:56 -07:00
while (testNode->x4_prio > pumpPrio)
{
testPrevNode = testNode;
testNode = testNode->x8_next;
}
node->x8_next = testNode;
if (testPrevNode)
testPrevNode->x8_next = node;
else
x4_pumpRoot = node;
2015-08-25 18:34:56 -07:00
break;
}
prevNode = node;
}
prevNode = nullptr;
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x0_drawRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
if (iow == toChange)
2015-08-25 18:34:56 -07:00
{
if (prevNode)
prevNode->x8_next = node->x8_next;
node->x4_prio = drawPrio;
IOWinPQNode* testNode = x0_drawRoot;
IOWinPQNode* testPrevNode = nullptr;
2015-08-25 18:34:56 -07:00
while (testNode->x4_prio > drawPrio)
{
testPrevNode = testNode;
testNode = testNode->x8_next;
}
node->x8_next = testNode;
if (testPrevNode)
testPrevNode->x8_next = node;
else
x0_drawRoot = node;
2015-08-25 18:34:56 -07:00
break;
}
prevNode = node;
}
}
void CIOWinManager::RemoveAllIOWins()
{
for (IOWinPQNode* node = x0_drawRoot ; node ;)
{
IOWinPQNode* n = node;
node = n->x8_next;
delete n;
}
2015-08-26 17:23:46 -07:00
x0_drawRoot = nullptr;
for (IOWinPQNode* node = x4_pumpRoot ; node ;)
{
IOWinPQNode* n = node;
node = n->x8_next;
delete n;
}
2015-08-26 17:23:46 -07:00
x4_pumpRoot = nullptr;
2015-08-25 18:34:56 -07:00
}
void CIOWinManager::RemoveIOWin(CIOWin* chIow)
2015-08-25 18:34:56 -07:00
{
IOWinPQNode* prevNode = nullptr;
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x4_pumpRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
2015-08-25 18:34:56 -07:00
if (iow == chIow)
{
if (prevNode)
prevNode->x8_next = node->x8_next;
else
x4_pumpRoot = node->x8_next;
2015-08-25 18:34:56 -07:00
delete node;
break;
}
prevNode = node;
}
prevNode = nullptr;
2016-09-13 22:54:09 -07:00
for (IOWinPQNode* node = x0_drawRoot ; node ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
{
CIOWin* iow = node->GetIOWin();
2015-08-25 18:34:56 -07:00
if (iow == chIow)
{
if (prevNode)
prevNode->x8_next = node->x8_next;
else
x0_drawRoot = node->x8_next;
2015-08-25 18:34:56 -07:00
delete node;
break;
}
prevNode = node;
}
}
void CIOWinManager::AddIOWin(std::weak_ptr<CIOWin> chIow, int pumpPrio, int drawPrio)
2015-08-25 18:34:56 -07:00
{
2016-09-13 22:54:09 -07:00
IOWinPQNode* node;
IOWinPQNode* prevNode = nullptr;
2016-09-13 22:54:09 -07:00
for (node = x4_pumpRoot ; node && pumpPrio < node->x4_prio ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
prevNode = node;
IOWinPQNode* newNode = new IOWinPQNode(chIow, pumpPrio, node);
2015-08-25 18:34:56 -07:00
if (prevNode)
prevNode->x8_next = newNode;
else
x4_pumpRoot = newNode;
2015-08-25 18:34:56 -07:00
prevNode = nullptr;
2016-09-13 22:54:09 -07:00
for (node = x0_drawRoot ; node && drawPrio < node->x4_prio ; node = node->x8_next)
2015-08-25 18:34:56 -07:00
prevNode = node;
newNode = new IOWinPQNode(chIow, drawPrio, node);
2015-08-25 18:34:56 -07:00
if (prevNode)
prevNode->x8_next = newNode;
else
x0_drawRoot = newNode;
2015-08-25 18:34:56 -07:00
}
2015-08-19 19:52:07 -07:00
}