http: Load actual game list.

This commit is contained in:
Unknown W. Brackets 2016-07-03 20:48:27 -07:00
parent c3e70c11f8
commit c793efd69a
4 changed files with 217 additions and 44 deletions

View File

@ -457,6 +457,18 @@ UI::EventReturn GameBrowser::PinToggleClick(UI::EventParams &e) {
return UI::EVENT_DONE;
}
bool GameBrowser::DisplayTopBar() {
return path_.GetPath() != "!RECENT";
}
bool GameBrowser::HasSpecialFiles(std::vector<std::string> &filenames) {
if (path_.GetPath() == "!RECENT") {
filenames = g_Config.recentIsos;
return true;
}
return false;
}
void GameBrowser::Refresh() {
using namespace UI;
@ -468,7 +480,7 @@ void GameBrowser::Refresh() {
I18NCategory *mm = GetI18NCategory("MainMenu");
// No topbar on recent screen
if (path_.GetPath() != "!RECENT") {
if (DisplayTopBar()) {
LinearLayout *topBar = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
if (allowBrowsing_) {
topBar->Add(new Spacer(2.0f));
@ -504,9 +516,10 @@ void GameBrowser::Refresh() {
std::vector<DirButton *> dirButtons;
std::vector<GameButton *> gameButtons;
if (path_.GetPath() == "!RECENT") {
for (size_t i = 0; i < g_Config.recentIsos.size(); i++) {
gameButtons.push_back(new GameButton(g_Config.recentIsos[i], *gridStyle_, new UI::LinearLayoutParams(*gridStyle_ == true ? UI::WRAP_CONTENT : UI::FILL_PARENT, UI::WRAP_CONTENT)));
std::vector<std::string> filenames;
if (HasSpecialFiles(filenames)) {
for (size_t i = 0; i < filenames.size(); i++) {
gameButtons.push_back(new GameButton(filenames[i], *gridStyle_, new UI::LinearLayoutParams(*gridStyle_ == true ? UI::WRAP_CONTENT : UI::FILL_PARENT, UI::WRAP_CONTENT)));
}
} else {
std::vector<FileInfo> fileInfo;

View File

@ -35,8 +35,13 @@ public:
void FocusGame(std::string gamePath);
private:
protected:
virtual bool DisplayTopBar();
virtual bool HasSpecialFiles(std::vector<std::string> &filenames);
void Refresh();
private:
bool IsCurrentPathPinned();
const std::vector<std::string> GetPinnedPaths();
const std::string GetBaseName(const std::string &path);
@ -61,6 +66,8 @@ private:
std::string focusGamePath_;
};
class RemoteISOBrowseScreen;
class MainScreen : public UIScreenWithBackground {
public:
MainScreen();
@ -78,7 +85,7 @@ protected:
virtual void sendMessage(const char *message, const char *value);
virtual void dialogFinished(const Screen *dialog, DialogResult result);
private:
bool UseVerticalLayout() const;
bool DrawBackgroundFor(UIContext &dc, const std::string &gamePath, float progress);
UI::EventReturn OnGameSelected(UI::EventParams &e);
@ -112,7 +119,7 @@ private:
bool lockBackgroundAudio_;
bool lastVertical_;
bool UseVerticalLayout() const;
friend class RemoteISOBrowseScreen;
};
class UmdReplaceScreen : public UIDialogScreenWithBackground {

View File

@ -178,7 +178,7 @@ static void ExecuteServer() {
UpdateStatus(ServerStatus::STOPPED);
}
static std::string FindServer() {
static bool FindServer(std::string &resultHost, int &resultPort) {
http::Client http;
Buffer result;
int code = 500;
@ -191,7 +191,7 @@ static std::string FindServer() {
}
if (code != 200) {
return "";
return false;
}
std::string json;
@ -199,12 +199,12 @@ static std::string FindServer() {
JsonReader reader(json.c_str(), json.size());
if (!reader.ok()) {
return "";
return false;
}
const json_value *entries = reader.root();
if (!entries) {
return "";
return false;
}
std::vector<std::string> servers;
@ -219,14 +219,50 @@ static std::string FindServer() {
if (http.Resolve(host, port) && http.Connect()) {
http.Disconnect();
return url;
resultHost = host;
resultPort = port;
return true;
}
entry = entry->next_sibling;
}
// None of the local IPs were reachable.
return "";
return false;
}
static bool LoadGameList(const std::string &host, int port, std::vector<std::string> &games) {
http::Client http;
Buffer result;
int code = 500;
// Start by requesting a list of recent local ips for this network.
if (http.Resolve(host.c_str(), port)) {
http.Connect();
code = http.GET("/", &result);
http.Disconnect();
}
if (code != 200) {
return false;
}
std::string listing;
std::vector<std::string> items;
result.TakeAll(&listing);
SplitString(listing, '\n', items);
for (const std::string &item : items) {
if (!endsWithNoCase(item, ".cso") && !endsWithNoCase(item, ".iso") && !endsWithNoCase(item, ".pbp")) {
continue;
}
char temp[1024] = {};
snprintf(temp, sizeof(temp) - 1, "http://%s:%d%s", host.c_str(), port, item.c_str());
games.push_back(temp);
}
return !games.empty();
}
RemoteISOScreen::RemoteISOScreen() : serverRunning_(false), serverStopping_(false) {
@ -324,8 +360,8 @@ UI::EventReturn RemoteISOScreen::HandleBrowse(UI::EventParams &e) {
return EVENT_DONE;
}
RemoteISOConnectScreen::RemoteISOConnectScreen() : scanComplete_(false), nextRetry_(0.0) {
scanLock_ = new recursive_mutex();
RemoteISOConnectScreen::RemoteISOConnectScreen() : status_(ScanStatus::SCANNING), nextRetry_(0.0) {
statusLock_ = new recursive_mutex();
scanThread_ = new std::thread([](RemoteISOConnectScreen *thiz) {
thiz->ExecuteScan();
@ -334,11 +370,11 @@ RemoteISOConnectScreen::RemoteISOConnectScreen() : scanComplete_(false), nextRet
}
RemoteISOConnectScreen::~RemoteISOConnectScreen() {
while (!scanComplete_) {
while (GetStatus() == ScanStatus::SCANNING || GetStatus() == ScanStatus::LOADING) {
sleep_ms(1);
}
delete scanThread_;
delete scanLock_;
delete statusLock_;
}
void RemoteISOConnectScreen::CreateViews() {
@ -351,7 +387,7 @@ void RemoteISOConnectScreen::CreateViews() {
ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins));
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL);
leftColumnItems->Add(new TextView(sy->T("RemoteISOScanning", "Scanning... click Share Games on your desktop"), new LinearLayoutParams(Margins(12, 5, 0, 5))));
statusView_ = leftColumnItems->Add(new TextView(sy->T("RemoteISOScanning", "Scanning... click Share Games on your desktop"), new LinearLayoutParams(Margins(12, 5, 0, 5))));
// TODO: Here would be a good place for manual entry.
@ -367,15 +403,36 @@ void RemoteISOConnectScreen::CreateViews() {
}
void RemoteISOConnectScreen::update(InputState &input) {
I18NCategory *sy = GetI18NCategory("System");
UIScreenWithBackground::update(input);
if (IsComplete()) {
if (!url_.empty()) {
BrowseToURL(url_);
} else if (nextRetry_ <= 0.0f) {
nextRetry_ = real_time_now() + 30.0;
} else if (nextRetry_ < real_time_now()) {
scanComplete_ = false;
ScanStatus s = GetStatus();
switch (s) {
case ScanStatus::SCANNING:
case ScanStatus::LOADING:
break;
case ScanStatus::FOUND:
statusView_->SetText(sy->T("RemoteISOLoading", "Connected - loading game list"));
status_ = ScanStatus::LOADING;
// Let's reuse scanThread_.
delete scanThread_;
scanThread_ = new std::thread([](RemoteISOConnectScreen *thiz) {
thiz->ExecuteLoad();
}, this);
scanThread_->detach();
break;
case ScanStatus::FAILED:
nextRetry_ = real_time_now() + 30.0;
status_ = ScanStatus::RETRY_SCAN;
break;
case ScanStatus::RETRY_SCAN:
if (nextRetry_ < real_time_now()) {
status_ = ScanStatus::SCANNING;
nextRetry_ = 0.0;
delete scanThread_;
@ -384,30 +441,110 @@ void RemoteISOConnectScreen::update(InputState &input) {
}, this);
scanThread_->detach();
}
break;
case ScanStatus::LOADED:
screenManager()->finishDialog(this, DR_OK);
screenManager()->push(new RemoteISOBrowseScreen(games_));
break;
}
}
void RemoteISOConnectScreen::ExecuteScan() {
url_ = FindServer();
FindServer(host_, port_);
lock_guard guard(*scanLock_);
scanComplete_ = true;
lock_guard guard(*statusLock_);
status_ = host_.empty() ? ScanStatus::FAILED : ScanStatus::FOUND;
}
bool RemoteISOConnectScreen::IsComplete() {
lock_guard guard(*scanLock_);
return scanComplete_;
ScanStatus RemoteISOConnectScreen::GetStatus() {
lock_guard guard(*statusLock_);
return status_;
}
void RemoteISOConnectScreen::BrowseToURL(const std::string &url) {
screenManager()->finishDialog(this, DR_OK);
screenManager()->push(new RemoteISOBrowseScreen(url));
void RemoteISOConnectScreen::ExecuteLoad() {
bool result = LoadGameList(host_, port_, games_);
lock_guard guard(*statusLock_);
status_ = result ? ScanStatus::LOADED : ScanStatus::FAILED;
}
RemoteISOBrowseScreen::RemoteISOBrowseScreen(const std::string &url) {
// TODO
class RemoteGameBrowser : public GameBrowser {
public:
RemoteGameBrowser(const std::vector<std::string> &games, bool allowBrowsing, bool *gridStyle_, std::string lastText, std::string lastLink, int flags = 0, UI::LayoutParams *layoutParams = 0)
: GameBrowser("!REMOTE", allowBrowsing, gridStyle_, lastText, lastLink, flags, layoutParams) {
games_ = games;
Refresh();
}
protected:
bool DisplayTopBar() override {
return false;
}
bool HasSpecialFiles(std::vector<std::string> &filenames) override;
std::vector<std::string> games_;
};
bool RemoteGameBrowser::HasSpecialFiles(std::vector<std::string> &filenames) {
filenames = games_;
return true;
}
RemoteISOBrowseScreen::RemoteISOBrowseScreen(const std::vector<std::string> &games) : games_(games) {
}
void RemoteISOBrowseScreen::CreateViews() {
// TODO
bool vertical = UseVerticalLayout();
I18NCategory *mm = GetI18NCategory("MainMenu");
I18NCategory *di = GetI18NCategory("Dialog");
Margins actionMenuMargins(0, 10, 10, 0);
TabHolder *leftColumn = new TabHolder(ORIENT_HORIZONTAL, 64, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
tabHolder_ = leftColumn;
tabHolder_->SetTag("RemoteGames");
gameBrowsers_.clear();
leftColumn->SetClip(true);
ScrollView *scrollRecentGames = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scrollRecentGames->SetTag("RemoteGamesTab");
RemoteGameBrowser *tabRemoteGames = new RemoteGameBrowser(
games_, false, &g_Config.bGridView1, "", "", 0,
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
scrollRecentGames->Add(tabRemoteGames);
gameBrowsers_.push_back(tabRemoteGames);
leftColumn->AddTab(mm->T("Remote Server"), scrollRecentGames);
tabRemoteGames->OnChoice.Handle<MainScreen>(this, &MainScreen::OnGameSelectedInstant);
tabRemoteGames->OnHoldChoice.Handle<MainScreen>(this, &MainScreen::OnGameSelected);
tabRemoteGames->OnHighlight.Handle<MainScreen>(this, &MainScreen::OnGameHighlight);
ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL);
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
rightColumnItems->SetSpacing(0.0f);
rightColumn->Add(rightColumnItems);
rightColumnItems->Add(new Choice(di->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
if (vertical) {
root_ = new LinearLayout(ORIENT_VERTICAL);
rightColumn->ReplaceLayoutParams(new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
leftColumn->ReplaceLayoutParams(new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0));
root_->Add(rightColumn);
root_->Add(leftColumn);
} else {
root_ = new LinearLayout(ORIENT_HORIZONTAL);
leftColumn->ReplaceLayoutParams(new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0));
rightColumn->ReplaceLayoutParams(new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins));
root_->Add(leftColumn);
root_->Add(rightColumn);
}
root_->SetDefaultFocusView(tabHolder_);
upgradeBar_ = 0;
}

View File

@ -21,6 +21,7 @@
#include "ui/ui_screen.h"
#include "ui/viewgroup.h"
#include "UI/MiscScreens.h"
#include "UI/MainScreen.h"
namespace std {
class thread;
@ -44,6 +45,15 @@ protected:
bool serverStopping_;
};
enum class ScanStatus {
SCANNING,
RETRY_SCAN,
FOUND,
FAILED,
LOADING,
LOADED,
};
class RemoteISOConnectScreen : public UIScreenWithBackground {
public:
RemoteISOConnectScreen();
@ -53,21 +63,27 @@ protected:
void update(InputState &input) override;
void CreateViews() override;
ScanStatus GetStatus();
void ExecuteScan();
bool IsComplete();
void BrowseToURL(const std::string &url);
void ExecuteLoad();
bool scanComplete_;
UI::TextView *statusView_;
ScanStatus status_;
double nextRetry_;
std::thread *scanThread_;
recursive_mutex *scanLock_;
std::string url_;
recursive_mutex *statusLock_;
std::string host_;
int port_;
std::vector<std::string> games_;
};
class RemoteISOBrowseScreen : public UIScreenWithBackground {
class RemoteISOBrowseScreen : public MainScreen {
public:
RemoteISOBrowseScreen(const std::string &url);
RemoteISOBrowseScreen(const std::vector<std::string> &games);
protected:
void CreateViews() override;
std::vector<std::string> games_;
};