CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/UI/GameInfoCache.h
Views: 1401
// Copyright (c) 2013- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#pragma once1819#include <string>20#include <map>21#include <memory>22#include <mutex>23#include <atomic>2425#include "Common/Thread/Event.h"26#include "Core/ELF/ParamSFO.h"27#include "Common/File/Path.h"2829namespace Draw {30class DrawContext;31class Texture;32}3334// A GameInfo holds information about a game, and also lets you do things that the VSH35// does on the PSP, namely checking for and deleting savedata, and similar things.36// Only cares about games that are installed on the current device.3738// A GameInfo object can also represent a piece of savedata.3940// Guessed from GameID, not necessarily accurate41enum GameRegion {42GAMEREGION_JAPAN,43GAMEREGION_USA,44GAMEREGION_EUROPE,45GAMEREGION_HONGKONG,46GAMEREGION_ASIA,47GAMEREGION_KOREA,48GAMEREGION_OTHER,49GAMEREGION_MAX,50};5152enum class GameInfoFlags {53FILE_TYPE = 0x01, // Don't need to specify this, always included.54PARAM_SFO = 0x02,55ICON = 0x04,56BG = 0x08,57SND = 0x10,58SIZE = 0x20,59UNCOMPRESSED_SIZE = 0x40,60};61ENUM_CLASS_BITOPS(GameInfoFlags);6263class FileLoader;64enum class IdentifiedFileType;6566struct GameInfoTex {67std::string data;68Draw::Texture *texture = nullptr;69// The time at which the Icon and the BG were loaded.70// Can be useful to fade them in smoothly once they appear.71// Also, timeLoaded != 0 && texture == nullptr means that the load failed.72double timeLoaded = 0.0;73std::atomic<bool> dataLoaded{};7475// Can ONLY be called from the main thread!76void Clear();77bool Failed() const {78return timeLoaded != 0.0 && !texture;79}80};8182class GameInfo {83public:84GameInfo(const Path &gamePath);85~GameInfo();8687bool Delete(); // Better be sure what you're doing when calling this.88bool DeleteAllSaveData();89bool CreateLoader();9091bool HasFileLoader() const {92return fileLoader.get() != nullptr;93}9495std::shared_ptr<FileLoader> GetFileLoader();96void DisposeFileLoader();9798u64 GetSizeUncompressedInBytes(); // NOTE: More expensive than GetGameSizeOnDiskInBytes().99u64 GetSizeOnDiskInBytes();100u64 GetGameSavedataSizeInBytes(); // For games101u64 GetInstallDataSizeInBytes();102103// For various kinds of savedata, mainly.104// NOTE: This one actually performs I/O directly, not cached.105std::string GetMTime() const;106107void ParseParamSFO();108const ParamSFOData &GetParamSFO() const {109_dbg_assert_(hasFlags & GameInfoFlags::PARAM_SFO);110return paramSFO;111}112void FinishPendingTextureLoads(Draw::DrawContext *draw);113114std::vector<Path> GetSaveDataDirectories();115116std::string GetTitle();117void SetTitle(const std::string &newTitle);118119const Path &GetFilePath() const {120return filePath_;121}122123bool Ready(GameInfoFlags flags) {124std::unique_lock<std::mutex> guard(lock);125// Avoid the operator, we want to check all the bits.126return ((int)hasFlags & (int)flags) == (int)flags;127}128129void MarkReadyNoLock(GameInfoFlags flags) {130hasFlags |= flags;131pendingFlags &= ~flags;132}133134GameInfoTex *GetBGPic() {135if (pic1.texture)136return &pic1;137if (pic0.texture)138return &pic0;139return nullptr;140}141142// Hold this when reading or writing from the GameInfo.143// Don't need to hold it when just passing around the pointer,144// and obviously also not when creating it and holding the only pointer145// to it.146std::mutex lock;147148// Controls access to the fileLoader pointer.149std::mutex loaderLock;150151// Keep track of what we have, or what we're processing.152// These are protected by the mutex. While pendingFlags != 0, something is being loaded.153GameInfoFlags hasFlags{};154GameInfoFlags pendingFlags{};155156std::string id;157std::string id_version;158int disc_total = 0;159int disc_number = 0;160int region = -1;161IdentifiedFileType fileType;162bool hasConfig = false;163164// Pre read the data, create a texture the next time (GL thread..)165GameInfoTex icon;166GameInfoTex pic0;167GameInfoTex pic1;168169std::string sndFileData;170std::atomic<bool> sndDataLoaded{};171172double lastAccessedTime = 0.0;173174u64 gameSizeUncompressed = 0;175u64 gameSizeOnDisk = 0; // compressed size, in case of CSO176u64 saveDataSize = 0;177u64 installDataSize = 0;178179protected:180ParamSFOData paramSFO;181// Note: this can change while loading, use GetTitle().182std::string title;183184// TODO: Get rid of this shared_ptr and managae lifetime better instead.185std::shared_ptr<FileLoader> fileLoader;186Path filePath_;187188void SetupTexture(Draw::DrawContext *draw, GameInfoTex &tex);189190private:191DISALLOW_COPY_AND_ASSIGN(GameInfo);192friend class GameInfoWorkItem;193};194195class GameInfoCache {196public:197GameInfoCache();198~GameInfoCache();199200// This creates a background worker thread!201void Clear();202void PurgeType(IdentifiedFileType fileType);203204// All data in GameInfo including icon.texture may be zero the first time you call this205// but filled in later asynchronously in the background. So keep calling this,206// redrawing the UI often. Only set flags to GAMEINFO_WANTBG or WANTSND if you really want them207// because they're big. bgTextures and sound may be discarded over time as well.208// NOTE: This never returns null, so you don't need to check for that. Do check Ready() flags though.209std::shared_ptr<GameInfo> GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags);210void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds.211212void CancelAll();213void WaitUntilDone(std::shared_ptr<GameInfo> &info);214215private:216void Init();217void Shutdown();218219// Maps ISO path to info. Need to use shared_ptr as we can return these pointers -220// and if they get destructed while being in use, that's bad.221std::map<std::string, std::shared_ptr<GameInfo> > info_;222std::mutex mapLock_;223};224225// This one can be global, no good reason not to.226extern GameInfoCache *g_gameInfoCache;227228229