summaryrefslogtreecommitdiff
path: root/src/s/s_StateMethod.cpp
blob: 96655a45358179a927d15e0e605d82b5d52d26eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "s/s_StateMethod.hpp"

#include "common.h"
#include "s/s_StateID.hpp"
#include "s/s_StateInterfaces.hpp"


// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made

sStateMethod_c::sStateMethod_c(sStateIDChkIf_c &checker, sStateFctIf_c &factory, const sStateIDIf_c &initialState)
    : mpStateChk(checker), mpStateFct(factory), mInitFinalizeLock(false), mExecutionLock(false), mIsValid(false),
      mStateChanged(false), mRefreshStateMethod(false), mpNewStateID(&initialState), mpOldStateID(&sStateID::null),
      mpStateID(&initialState), mpState(nullptr) {}

sStateMethod_c::~sStateMethod_c() {}

void sStateMethod_c::initializeStateMethod() {
    if (!mpNewStateID->isNull() && !mInitFinalizeLock && !mIsValid) {
        mInitFinalizeLock = true;

        mpStateID = mpNewStateID;
        int ret = initializeStateLocalMethod();
        if (ret != 0) {
            mIsValid = true;
        } else {
            mIsValid = false;
        }

        mInitFinalizeLock = false;
    }
}

void sStateMethod_c::executeStateMethod() {
    if (!mExecutionLock) {
        // Skyward Sword change: Prevent runaway state changes?
        int i = 2;
        do {
            if (mRefreshStateMethod) {
                i--;
            }
            mRefreshStateMethod = false;
            // We only want to execute if we have a valid next state
            if (!mpNewStateID->isNull()) {
                mExecutionLock = true;
                executeStateLocalMethod();
                mExecutionLock = false;
            }
        } while (mRefreshStateMethod && mStateChanged && i);
    }
}

void sStateMethod_c::finalizeStateMethod() {
    if (!mpNewStateID->isNull() && mIsValid && !mInitFinalizeLock) {
        mInitFinalizeLock = true;

        mpOldStateID = mpStateID;
        finalizeStateLocalMethod();
        mIsValid = false;

        mInitFinalizeLock = false;
    }
}

void sStateMethod_c::changeStateMethod(const sStateIDIf_c &newID) {
    if (!newID.isNull()) {
        mpNewStateID = &newID;
        changeStateLocalMethod(newID);
        mStateChanged = true;
    }
}