Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async improvements + Async Inn Sequence #1887

Merged
merged 4 commits into from
Sep 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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