mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
implement PointerWrap::DoLinkedList and use it to simplify saving CoreTiming events
This commit is contained in:
@ -179,10 +179,64 @@ public:
|
|||||||
DoVoid((void *)&x, sizeof(x));
|
DoVoid((void *)&x, sizeof(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)>
|
||||||
void DoLinkedList(LinkedListItem<T> **list_start) {
|
void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end=0)
|
||||||
// TODO
|
{
|
||||||
PanicAlert("Do(linked list<>) does not yet work.");
|
LinkedListItem<T>* list_cur = list_start;
|
||||||
|
LinkedListItem<T>* prev = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
u8 shouldExist = (list_cur ? 1 : 0);
|
||||||
|
Do(shouldExist);
|
||||||
|
if (shouldExist == 1)
|
||||||
|
{
|
||||||
|
LinkedListItem<T>* cur = list_cur ? list_cur : TNew();
|
||||||
|
TDo(*this, (T*)cur);
|
||||||
|
if (!list_cur)
|
||||||
|
{
|
||||||
|
if (mode == MODE_READ)
|
||||||
|
{
|
||||||
|
cur->next = 0;
|
||||||
|
list_cur = cur;
|
||||||
|
if (prev)
|
||||||
|
prev->next = cur;
|
||||||
|
else
|
||||||
|
list_start = cur;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TFree(cur);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mode == MODE_READ)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
prev->next = 0;
|
||||||
|
if (list_end)
|
||||||
|
*list_end = prev;
|
||||||
|
if (list_cur)
|
||||||
|
{
|
||||||
|
if (list_start == list_cur)
|
||||||
|
list_start = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
LinkedListItem<T>* next = list_cur->next;
|
||||||
|
TFree(list_cur);
|
||||||
|
list_cur = next;
|
||||||
|
}
|
||||||
|
while (list_cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = list_cur;
|
||||||
|
list_cur = list_cur->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoMarker(const char* prevName, u32 arbitraryNumber=0x42)
|
void DoMarker(const char* prevName, u32 arbitraryNumber=0x42)
|
||||||
|
@ -47,7 +47,7 @@ struct BaseEvent
|
|||||||
|
|
||||||
typedef LinkedListItem<BaseEvent> Event;
|
typedef LinkedListItem<BaseEvent> Event;
|
||||||
|
|
||||||
// STATE_TO_SAVE (how?)
|
// STATE_TO_SAVE
|
||||||
Event *first;
|
Event *first;
|
||||||
Event *tsFirst;
|
Event *tsFirst;
|
||||||
Event *tsLast;
|
Event *tsLast;
|
||||||
@ -153,6 +153,13 @@ void Shutdown()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventDoState(PointerWrap &p, BaseEvent* ev)
|
||||||
|
{
|
||||||
|
p.Do(ev->time);
|
||||||
|
p.Do(ev->type);
|
||||||
|
p.Do(ev->userdata);
|
||||||
|
}
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
|
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
|
||||||
@ -165,53 +172,12 @@ void DoState(PointerWrap &p)
|
|||||||
p.Do(fakeTBStartValue);
|
p.Do(fakeTBStartValue);
|
||||||
p.Do(fakeTBStartTicks);
|
p.Do(fakeTBStartTicks);
|
||||||
p.DoMarker("CoreTimingData");
|
p.DoMarker("CoreTimingData");
|
||||||
// OK, here we're gonna need to specialize depending on the mode.
|
|
||||||
// Should do something generic to serialize linked lists.
|
p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, EventDoState>(first);
|
||||||
switch (p.GetMode()) {
|
|
||||||
case PointerWrap::MODE_READ:
|
|
||||||
{
|
|
||||||
ClearPendingEvents();
|
|
||||||
if (first)
|
|
||||||
PanicAlertT("Clear failed.");
|
|
||||||
int more_events = 0;
|
|
||||||
Event *prev = 0;
|
|
||||||
while (true) {
|
|
||||||
p.Do(more_events);
|
|
||||||
if (!more_events)
|
|
||||||
break;
|
|
||||||
Event *ev = GetNewEvent();
|
|
||||||
if (!prev)
|
|
||||||
first = ev;
|
|
||||||
else
|
|
||||||
prev->next = ev;
|
|
||||||
p.Do(ev->time);
|
|
||||||
p.Do(ev->type);
|
|
||||||
p.Do(ev->userdata);
|
|
||||||
ev->next = 0;
|
|
||||||
prev = ev;
|
|
||||||
ev = ev->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PointerWrap::MODE_MEASURE:
|
|
||||||
case PointerWrap::MODE_VERIFY:
|
|
||||||
case PointerWrap::MODE_WRITE:
|
|
||||||
{
|
|
||||||
Event *ev = first;
|
|
||||||
int more_events = 1;
|
|
||||||
while (ev) {
|
|
||||||
p.Do(more_events);
|
|
||||||
p.Do(ev->time);
|
|
||||||
p.Do(ev->type);
|
|
||||||
p.Do(ev->userdata);
|
|
||||||
ev = ev->next;
|
|
||||||
}
|
|
||||||
more_events = 0;
|
|
||||||
p.Do(more_events);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.DoMarker("CoreTimingEvents");
|
p.DoMarker("CoreTimingEvents");
|
||||||
|
|
||||||
|
p.DoLinkedList<BaseEvent, GetNewTsEvent, FreeTsEvent, EventDoState>(tsFirst, &tsLast);
|
||||||
|
p.DoMarker("CoreTimingTsEvents");
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetTicks()
|
u64 GetTicks()
|
||||||
|
Reference in New Issue
Block a user