Adds LoadScene.

This commit is contained in:
falsycat 2021-08-28 13:27:42 +09:00
parent e50625fd1b
commit 7fa5227f42
11 changed files with 146 additions and 40 deletions

View File

@ -150,6 +150,7 @@
<ClCompile Include="src\Font.cc" />
<ClCompile Include="src\Game.cc" />
<ClCompile Include="src\HiraganaMatcher.cc" />
<ClCompile Include="src\LoadScene.cc" />
<ClCompile Include="src\Lua.cc" />
<ClCompile Include="src\main.cc" />
<ClCompile Include="src\PlayScene.cc" />
@ -177,6 +178,7 @@
<ClInclude Include="src\InputWindowElementFactory.h" />
<ClInclude Include="src\iScene.h" />
<ClInclude Include="src\iWritable.h" />
<ClInclude Include="src\LoadScene.h" />
<ClInclude Include="src\Logger.h" />
<ClInclude Include="src\Lua.h" />
<ClInclude Include="src\Music.h" />

View File

@ -51,6 +51,9 @@
<ClCompile Include="src\TitleScene.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LoadScene.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\iConsole.h">
@ -215,6 +218,9 @@
<ClInclude Include="src\Music.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\LoadScene.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Library Include="thirdparty\lua5.1.lib" />

View File

@ -15,13 +15,13 @@ class ElementStore {
public:
ElementStore() = delete;
ElementStore(ElementStore&&) = delete;
ElementStore(ElementStore&&) = default;
ElementStore(const ElementStore&) = delete;
ElementStore& operator=(ElementStore&&) = delete;
ElementStore& operator=(ElementStore&&) = default;
ElementStore& operator=(const ElementStore&) = delete;
ElementStore(iClock* clock, size_t reserve) : clock_(clock) {
ElementStore(size_t reserve) {
pending_.reserve(reserve);
performing_.reserve(reserve);
}
@ -35,9 +35,7 @@ class ElementStore {
pending_.insert(insert_pos, std::move(e));
}
void Update(Frame& frame) {
const uint64_t now = clock_->now();
void Update(Frame& frame, uint64_t now) {
auto pending_beg = pending_.begin();
auto pending_end = pending_.end();
auto pending_itr = pending_beg;
@ -83,8 +81,6 @@ class ElementStore {
}
private:
const iClock* clock_;
std::vector<UniqPtr<iElement>> pending_;
std::vector<UniqPtr<iElement>> performing_;
};

View File

@ -27,7 +27,7 @@ class GlyphElementFactory : public iElementFactory {
const std::string text = std::get<std::string>(param.custom[0]);
const std::string name = std::get<std::string>(param.custom[1]);
const intmax_t size = std::get<double>(param.custom[2]);
const uint32_t size = static_cast<uint32_t>(std::get<double>(param.custom[2]));
auto& font = FindOrCreateFont(name);
auto tex = std::move(font.RenderGlyphs(ConvertStrToWstr(text), size)); /* TODO */

26
src/LoadScene.cc Normal file
View File

@ -0,0 +1,26 @@
#include "LoadScene.h"
#include "common.h"
gj::LoadScene::LoadScene(Param&& p) :
alloc_(p.super.alloc), clock_(p.super.clock), loading_(L"Loading...") {
prod_ = p.super.alloc->MakeUniq<PlayScene>(p.super, p.title, p.path);
orphan_ = std::move(p.orphan);
}
gj::UniqPtr<gj::iScene> gj::LoadScene::Update(Frame& frame) {
if (prod_->HasPrepared() && !(orphan_ && orphan_->IsBusy())) {
prod_->Start();
return UniqPtr<iScene>(prod_.release(), iAllocator::Deleter<iScene>(alloc_));
}
const uint64_t now = clock_->now();
if (XorShift(now+1)%10) {
loading_.SetPosition((frame.w - loading_.width())/2, frame.h/2);
frame.Add(&loading_);
}
return nullptr;
}

50
src/LoadScene.h Normal file
View File

@ -0,0 +1,50 @@
#pragma once
#include <string>
#include "iAllocator.h"
#include "iClock.h"
#include "iScene.h"
#include "Music.h"
#include "PlayScene.h"
#include "Text.h"
namespace gj {
class LoadScene : public iScene {
public:
struct Param {
iScene::Param super;
std::string title;
std::string path;
/* 'orphan' is an instance of Music that couldn't be deleted
* at previous scene because it was busy. */
UniqPtr<Music> orphan;
};
LoadScene() = delete;
LoadScene(LoadScene&&) = delete;
LoadScene(const LoadScene&) = delete;
LoadScene& operator=(LoadScene&&) = delete;
LoadScene& operator=(const LoadScene&) = delete;
LoadScene(Param&& p);
UniqPtr<iScene> Update(Frame& frame) override;
private:
iAllocator* alloc_;
const iClock* clock_;
UniqPtr<PlayScene> prod_;
UniqPtr<Music> orphan_;
Text loading_;
};
}

View File

@ -19,16 +19,25 @@ class Lua {
using FactoryMap = std::map<std::string, iElementFactory*>;
Lua() = delete;
Lua(Lua&&) = delete;
Lua(const Lua&) = delete;
Lua& operator=(Lua&&) = delete;
Lua& operator=(const Lua&) = delete;
Lua(Lua&& src) noexcept : L(src.L) {
src.L = nullptr;
}
Lua& operator=(Lua&& src) noexcept {
if (&src != this) {
L = src.L;
src.L = nullptr;
}
return *this;
}
Lua(iAllocator* alloc, ElementStore* store, const FactoryMap& factory, const std::string& path);
~Lua() {
lua_close(L);
if (L) lua_close(L);
}
private:

View File

@ -7,8 +7,17 @@
#include "ResultScene.h"
gj::UniqPtr<gj::iScene> gj::PlayScene::Update(Frame& f) {
if (store_.IsEmpty()) {
return param_.alloc->MakeUniq<iScene, ResultScene>(param_, sb_);
}
store_.Update(f, clock_.now());
return nullptr;
}
gj::PlayScene::PlayScene(const Param& p, const std::string& title, const std::string& path) :
param_(p), clock_(p.clock), store_(&clock_, 256) {
param_(p), clock_(p.clock), store_(256) {
GlyphElementFactory glyph(p.alloc);
InputWindowElementFactory inputWin(p.alloc, &sb_);
@ -21,16 +30,13 @@ gj::PlayScene::PlayScene(const Param& p, const std::string& title, const std::st
{ "InputWin", &inputWin },
{ "Music", &music },
};
lua_ = p.alloc->MakeUniq<Lua>(
p.alloc, &store_, map, path);
lua_ = p.alloc->MakeUniq<Lua>(p.alloc, &store_, map, path);
}
gj::UniqPtr<gj::iScene> gj::PlayScene::Update(Frame& f) {
if (store_.IsEmpty()) {
return param_.alloc->MakeUniq<iScene, ResultScene>(param_, sb_);
}
store_.Update(f);
return nullptr;
void gj::PlayScene::Start() {
clock_ = OffsetClock(param_.clock);
}
bool gj::PlayScene::HasPrepared() const {
return store_.CountPreparings() == 0;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <string>
#include "ElementStore.h"
#include "iScene.h"
@ -13,6 +14,8 @@ namespace gj {
class PlayScene : public iScene {
public:
friend class LoadScene;
PlayScene() = delete;
PlayScene(PlayScene&&) = delete;
PlayScene(const PlayScene&) = delete;
@ -25,6 +28,9 @@ class PlayScene : public iScene {
UniqPtr<iScene> Update(Frame& f) override;
private:
void Start();
bool HasPrepared() const;
Param param_;
OffsetClock clock_;

View File

@ -10,12 +10,12 @@
#include "common.h"
#include "Font.h"
#include "PlayScene.h"
#include "LoadScene.h"
gj::TitleScene::TitleScene(const Param& p) :
param_(p),
score_(L"penguin: you didn't see anything..."),
title_(L"penguin: you didn't see anything..."),
next_(L"> L"), prev_(L"H <"),
guide_(L"H:PREV / SPACE:PLAY / L:NEXT"),
logo_(Colorbuffer(p.alloc, 1, 1)) {
@ -35,11 +35,10 @@ gj::TitleScene::TitleScene(const Param& p) :
auto& obj = e.get<::picojson::object>();
Score s;
s.displayName = obj["displayName"].get<std::string>();
s.music = obj["music"].get<std::string>();
s.score = obj["score"].get<std::string>();
s.playOffset = obj["playOffset"].get<double>();
s.title = obj["title"].get<std::string>();
s.music = obj["music"].get<std::string>();
s.path = obj["path"].get<std::string>();
s.playOffset = obj["playOffset"].get<double>();
list_.push_back(s);
}
@ -56,16 +55,22 @@ gj::UniqPtr<gj::iScene> gj::TitleScene::Update(Frame& frame) {
/* input handling */
for (const auto c : frame.input) {
switch (c) {
case ' ': {
if (music_) param_.audio->RemoveEffect(music_.get());
const auto& s = list_[select_index_];
LoadScene::Param param;
param.super = param_;
param.path = s.path;
param.title = s.title;
param.orphan = std::move(music_);
return param_.alloc->MakeUniq<iScene, LoadScene>(std::move(param));
}
case 'h':
SelectScore_(select_index_? select_index_-1: list_.size()-1);
break;
case 'l':
SelectScore_((select_index_+1)%list_.size());
break;
case ' ':
if (music_) param_.audio->RemoveEffect(music_.get());
return param_.alloc->MakeUniq<iScene, PlayScene>(
param_, list_[select_index_].displayName, list_[select_index_].score);
}
}
@ -126,8 +131,8 @@ gj::UniqPtr<gj::iScene> gj::TitleScene::Update(Frame& frame) {
prev_.SetPosition(static_cast<int32_t>(w*.2), selector_y);
frame.Add(&prev_);
score_.SetPosition((w-score_.width())/2, selector_y);
frame.Add(&score_);
title_.SetPosition((w-title_.width())/2, selector_y);
frame.Add(&title_);
guide_.SetPosition((w-guide_.width())/2, selector_y+3);
frame.Add(&guide_);
@ -141,7 +146,7 @@ gj::UniqPtr<gj::iScene> gj::TitleScene::Update(Frame& frame) {
void gj::TitleScene::SelectScore_(size_t index) {
const auto& s = list_[index];
score_ = Text(ConvertStrToWstr(s.displayName));
title_ = Text(ConvertStrToWstr(s.title));
select_index_ = index;
trying_play_ = true;

View File

@ -27,15 +27,15 @@ class TitleScene : public iScene {
private:
struct Score {
std::string displayName;
std::string score;
std::string title;
std::string path;
std::string music;
double playOffset = 0;
};
Param param_;
Text score_;
Text title_;
Text next_;
Text prev_;
Text guide_;