Skip to content

Commit

Permalink
Merge pull request #1887 from fmatthew5876/async_inn
Browse files Browse the repository at this point in the history
Async improvements + Async Inn Sequence
  • Loading branch information
Ghabry authored Sep 22, 2019
2 parents 05d07c7 + 23ea69f commit 0dc2675
Show file tree
Hide file tree
Showing 22 changed files with 453 additions and 300 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_library(${PROJECT_NAME}
src/3ds_ui.h
src/async_handler.cpp
src/async_handler.h
src/async_op.h
src/audio_3ds.cpp
src/audio_3ds.h
src/audio_al.cpp
Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ libeasyrpg_player_a_SOURCES = \
src/3ds_ui.h \
src/async_handler.cpp \
src/async_handler.h \
src/async_op.h \
src/audio.cpp \
src/audio.h \
src/audio_3ds.cpp \
Expand Down
119 changes: 119 additions & 0 deletions src/async_op.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef EP_ASYNC_OP_H
#define EP_ASYNC_OP_H

#include <utility>
#include <cassert>

/**
* Represents an asynchronous game operation. These are usually created
* by event interpreters. When an async operation starts, the entire game
* loop is supposed to suspend, perform the async operation, and
* then resume from the suspension point.
**/
class AsyncOp {
public:
/** The different types of async operations */
enum Type {
eNone,
eShowScreen,
eEraseScreen,
eCallInn,
eToTitle,
eExitGame
};

AsyncOp() = default;

/** @return a ShowScreen async operation */
static AsyncOp MakeShowScreen(int transition_type);

/** @return an EraseScreen async operation */
static AsyncOp MakeEraseScreen(int transition_type);

/** @return an CallInn async operation */
static AsyncOp MakeCallInn();

/** @return a ToTitle async operation */
static AsyncOp MakeToTitle();

/** @return an ExitGame async operation */
static AsyncOp MakeExitGame();

/** @return the type of async operation */
Type GetType() const;

/** @return true if this AsyncOp is active */
bool IsActive() const;

/**
* @return the type of screen transition to perform
* @pre If GetType() is not eShowScreen or eEraseScreen, the return value is undefined.
**/
int GetTransitionType() const;

private:
Type _type = eNone;
int _args[1] = {};

template <typename... Args>
explicit AsyncOp(Type type, Args&&... args);

};

inline AsyncOp::Type AsyncOp::GetType() const {
return _type;
}

inline bool AsyncOp::IsActive() const {
return GetType() != eNone;
}

inline int AsyncOp::GetTransitionType() const {
assert(GetType() == eShowScreen || GetType() == eEraseScreen);
return _args[0];
}

template <typename... Args>
inline AsyncOp::AsyncOp(Type type, Args&&... args)
: _type(type), _args{std::forward<Args>(args)...}
{}

inline AsyncOp AsyncOp::MakeShowScreen(int transition_type) {
return AsyncOp(eShowScreen, transition_type);
}

inline AsyncOp AsyncOp::MakeEraseScreen(int transition_type) {
return AsyncOp(eEraseScreen, transition_type);
}

inline AsyncOp AsyncOp::MakeCallInn() {
return AsyncOp(eCallInn);
}

inline AsyncOp AsyncOp::MakeToTitle() {
return AsyncOp(eToTitle);
}

inline AsyncOp AsyncOp::MakeExitGame() {
return AsyncOp(eExitGame);
}

#endif

6 changes: 3 additions & 3 deletions src/game_commonevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ void Game_CommonEvent::SetSaveData(const RPG::SaveEventExecState& data) {
}
}

bool Game_CommonEvent::Update() {
AsyncOp Game_CommonEvent::Update() {
if (interpreter && IsWaitingBackgroundExecution()) {
assert(interpreter->IsRunning());
interpreter->Update();

// Suspend due to async op ...
if (interpreter->IsAsyncPending()) {
return false;
return interpreter->GetAsyncOp();
}
}

return true;
return {};
}

int Game_CommonEvent::GetIndex() const {
Expand Down
12 changes: 3 additions & 9 deletions src/game_commonevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "game_interpreter_map.h"
#include "rpg_commonevent.h"
#include "rpg_saveeventexecstate.h"
#include "async_op.h"

/**
* Game_CommonEvent class.
Expand All @@ -47,9 +48,9 @@ class Game_CommonEvent {
/**
* Updates common event parallel interpreter.
*
* @return false if we must suspend due to an async operation.
* @return async operation if we should suspend, otherwise returns AsyncOp::eNone
*/
bool Update();
AsyncOp Update();

/**
* Gets common event index.
Expand Down Expand Up @@ -101,18 +102,11 @@ class Game_CommonEvent {
/** @return true if waiting for background execution */
bool IsWaitingBackgroundExecution() const;

/** @return true if parallel event waiting for async op */
bool IsAsyncPending() const;

private:
int common_event_id;

/** Interpreter for parallel common events. */
std::unique_ptr<Game_Interpreter_Map> interpreter;
};

inline bool Game_CommonEvent::IsAsyncPending() const {
return interpreter && interpreter->IsAsyncPending();
}

#endif
12 changes: 6 additions & 6 deletions src/game_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,9 +498,9 @@ void Game_Event::MoveTypeAwayFromPlayer() {
MoveTypeTowardsOrAwayPlayer(false);
}

bool Game_Event::Update() {
AsyncOp Game_Event::Update() {
if (!data()->active || page == NULL) {
return true;
return {};
}

// RPG_RT runs the parallel interpreter everytime Update is called.
Expand All @@ -516,18 +516,18 @@ bool Game_Event::Update() {

// Suspend due to async op ...
if (interpreter->IsAsyncPending()) {
return false;
return interpreter->GetAsyncOp();
}

// RPG_RT only exits if active is false here, but not if there is
// no active page...
if (!data()->active) {
return true;
return {};
}
}

if (IsProcessed()) {
return true;
return {};
}
SetProcessed(true);

Expand All @@ -545,7 +545,7 @@ bool Game_Event::Update() {
if (IsStopping()) {
CheckEventCollision();
}
return true;
return {};
}

const RPG::EventPage* Game_Event::GetPage(int page) const {
Expand Down
5 changes: 3 additions & 2 deletions src/game_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "rpg_event.h"
#include "rpg_savemapevent.h"
#include "game_interpreter_map.h"
#include "async_op.h"

/**
* Game_Event class.
Expand Down Expand Up @@ -111,9 +112,9 @@ class Game_Event : public Game_Character {
/**
* Update this for the current frame
*
* @return false if we must suspend due to an async operation.
* @return async operation if we should suspend, otherwise returns AsyncOp::eNone
*/
bool Update();
AsyncOp Update();

bool AreConditionsMet(const RPG::EventPage& page);

Expand Down
Loading

0 comments on commit 0dc2675

Please sign in to comment.