mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-02 02:23:56 +00:00
* WIP * WIP * Make camera the single source of truth for broadcast state Remove redundant local copies of walkAnimId, idleAnimId, and displayActorIndex from NetworkManager. BroadcastLocalState now reads these from the camera's Controller, eliminating dual-copy sync issues. Additional cleanup: - Early-return on null cam in SendEmote/HandleCustomize for clarity - Only consume camera-dependent pending requests when cam is available - Move local name bubble creation from BroadcastLocalState to Tickle - Remove dead NetworkManager::SetDisplayActorIndex method Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix clang format --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
207 lines
4.6 KiB
C++
207 lines
4.6 KiB
C++
#include "mxnotificationmanager.h"
|
|
|
|
#include "compat.h"
|
|
#include "decomp.h"
|
|
#include "extensions/siloader.h"
|
|
#include "mxautolock.h"
|
|
#include "mxmisc.h"
|
|
#include "mxnotificationparam.h"
|
|
#include "mxparam.h"
|
|
#include "mxticklemanager.h"
|
|
#include "mxtypes.h"
|
|
|
|
DECOMP_SIZE_ASSERT(MxNotification, 0x08);
|
|
DECOMP_SIZE_ASSERT(MxNotificationManager, 0x40);
|
|
|
|
using namespace Extensions;
|
|
|
|
// FUNCTION: LEGO1 0x100ac220
|
|
MxNotification::MxNotification(MxCore* p_target, const MxNotificationParam& p_param)
|
|
{
|
|
m_target = p_target;
|
|
m_param = p_param.Clone();
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac240
|
|
MxNotification::~MxNotification()
|
|
{
|
|
delete m_param;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac250
|
|
// FUNCTION: BETA10 0x10125805
|
|
MxNotificationManager::MxNotificationManager() : MxCore(), m_lock(), m_listenerIds()
|
|
{
|
|
m_unk0x2c = 0;
|
|
m_queue = NULL;
|
|
m_active = TRUE;
|
|
m_sendList = NULL;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac450
|
|
MxNotificationManager::~MxNotificationManager()
|
|
{
|
|
AUTOLOCK(m_lock);
|
|
Tickle();
|
|
delete m_queue;
|
|
m_queue = NULL;
|
|
|
|
TickleManager()->UnregisterClient(this);
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac600
|
|
MxResult MxNotificationManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
|
|
{
|
|
MxResult result = SUCCESS;
|
|
m_queue = new MxNotificationPtrList();
|
|
|
|
if (m_queue == NULL) {
|
|
result = FAILURE;
|
|
}
|
|
else {
|
|
TickleManager()->RegisterClient(this, 10);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac6c0
|
|
// FUNCTION: BETA10 0x10125b57
|
|
MxResult MxNotificationManager::Send(MxCore* p_listener, const MxNotificationParam& p_param)
|
|
{
|
|
AUTOLOCK(m_lock);
|
|
|
|
if (!m_active) {
|
|
return FAILURE;
|
|
}
|
|
|
|
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
|
if (it == m_listenerIds.end()) {
|
|
return FAILURE;
|
|
}
|
|
|
|
MxNotification* notif = new MxNotification(p_listener, p_param);
|
|
if (notif != NULL) {
|
|
m_queue->push_back(notif);
|
|
return SUCCESS;
|
|
}
|
|
|
|
return FAILURE;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac800
|
|
MxResult MxNotificationManager::Tickle()
|
|
{
|
|
m_sendList = new MxNotificationPtrList();
|
|
if (m_sendList == NULL) {
|
|
return FAILURE;
|
|
}
|
|
else {
|
|
{
|
|
AUTOLOCK(m_lock);
|
|
MxNotificationPtrList* temp1 = m_queue;
|
|
MxNotificationPtrList* temp2 = m_sendList;
|
|
m_queue = temp2;
|
|
m_sendList = temp1;
|
|
}
|
|
|
|
while (m_sendList->size() != 0) {
|
|
MxNotification* notif = m_sendList->front();
|
|
m_sendList->pop_front();
|
|
|
|
if (notif->GetParam()->GetNotification() == c_notificationEndAction) {
|
|
Extension<SiLoaderExt>::Call(SI::HandleEndAction, (MxEndActionNotificationParam&) *notif->GetParam());
|
|
}
|
|
|
|
notif->GetTarget()->Notify(*notif->GetParam());
|
|
delete notif;
|
|
}
|
|
|
|
delete m_sendList;
|
|
m_sendList = NULL;
|
|
return SUCCESS;
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100ac990
|
|
void MxNotificationManager::FlushPending(MxCore* p_listener)
|
|
{
|
|
MxNotificationPtrList pending;
|
|
MxNotification* notif;
|
|
|
|
{
|
|
AUTOLOCK(m_lock);
|
|
|
|
// Find all notifications from, and addressed to, p_listener.
|
|
if (m_sendList != NULL) {
|
|
MxNotificationPtrList::iterator it = m_sendList->begin();
|
|
while (it != m_sendList->end()) {
|
|
notif = *it;
|
|
if (notif->GetTarget()->GetId() == p_listener->GetId() ||
|
|
(notif->GetParam()->GetSender() && notif->GetParam()->GetSender()->GetId() == p_listener->GetId()
|
|
)) {
|
|
m_sendList->erase(it++);
|
|
pending.push_back(notif);
|
|
}
|
|
else {
|
|
it++;
|
|
}
|
|
}
|
|
}
|
|
|
|
MxNotificationPtrList::iterator it = m_queue->begin();
|
|
while (it != m_queue->end()) {
|
|
notif = *it;
|
|
if (notif->GetTarget()->GetId() == p_listener->GetId() ||
|
|
(notif->GetParam()->GetSender() && notif->GetParam()->GetSender()->GetId() == p_listener->GetId())) {
|
|
m_queue->erase(it++);
|
|
pending.push_back(notif);
|
|
}
|
|
else {
|
|
it++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Deliver those notifications.
|
|
while (pending.size() != 0) {
|
|
notif = pending.front();
|
|
pending.pop_front();
|
|
|
|
if (notif->GetParam()->GetNotification() == c_notificationEndAction) {
|
|
Extension<SiLoaderExt>::Call(SI::HandleEndAction, (MxEndActionNotificationParam&) *notif->GetParam());
|
|
}
|
|
|
|
notif->GetTarget()->Notify(*notif->GetParam());
|
|
delete notif;
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100acd20
|
|
// STUB: BETA10 0x1012666a
|
|
void MxNotificationManager::Register(MxCore* p_listener)
|
|
{
|
|
AUTOLOCK(m_lock);
|
|
|
|
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
|
if (it != m_listenerIds.end()) {
|
|
return;
|
|
}
|
|
|
|
m_listenerIds.push_back(p_listener->GetId());
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x100acdf0
|
|
// FUNCTION: BETA10 0x10126785
|
|
void MxNotificationManager::Unregister(MxCore* p_listener)
|
|
{
|
|
AUTOLOCK(m_lock);
|
|
|
|
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
|
|
|
if (it != m_listenerIds.end()) {
|
|
m_listenerIds.erase(it);
|
|
FlushPending(p_listener);
|
|
}
|
|
}
|