sdmc:/ and romfs:/ drawable loading, themeref refcounting and container gc (and not inner const anymore)

This commit is contained in:
zetaPRIME 2017-04-30 13:24:29 -04:00
parent a4d23ea438
commit 2e4d55a1ff
3 changed files with 68 additions and 12 deletions

View File

@ -181,10 +181,16 @@ void ThemeManager::End() {
void ThemeManager::GC() { void ThemeManager::GC() {
constexpr const int keepCycles = 5; // how many gc sweeps a drawable gets to stay loaded without being used constexpr const int keepCycles = 5; // how many gc sweeps a drawable gets to stay loaded without being used
std::vector<string> rem;
// WIP // WIP
for (auto& d : drawables) { for (auto& d : drawables) {
if (++d.second.lastAccess > keepCycles) d.second.Unload(); if (++d.second.lastAccess > keepCycles) {
d.second.Unload();
if (d.second.refCount <= 0) rem.push_back(d.first); // mark for full removal when no references exist
} }
}
for (auto& s : rem) drawables.erase(s); // and remove everything queued
} }
ThemeRef<Drawable> ThemeManager::GetAsset(const std::string& name) { ThemeRef<Drawable> ThemeManager::GetAsset(const std::string& name) {
@ -268,28 +274,50 @@ string ThemeManager::ResolveAssetPath(const string& id) {
//struct stat buf; //struct stat buf;
//string path(id.length() + 64, ' '); // preallocate buffer space //string path(id.length() + 64, ' '); // preallocate buffer space
static const string pfxLocal = "app:/"; string pfx = "";
if (id.compare(0, pfxLocal.length(), pfxLocal) == 0) {
size_t cpos = id.find(":/");
if (cpos != string::npos) {
pfx = id.substr(0, cpos);
cpos += 2;
} else cpos = 0;
if (pfx == "app") {
string sid = id.substr(cpos); // strip off the "app:/"
// app-local asset // app-local asset
// check if present in theme/app/[appname]/, else check in romfs // check if present in theme/app/[appname]/, else check in romfs
for (auto thm : themeData) { for (auto thm : themeData) {
Path bp = thm.basePath.Combine("app").Combine(Application::AppName()); Path bp = thm.basePath.Combine("app").Combine(Application::AppName());
Path p = bp.Combine(id+".json"); Path p = bp.Combine(sid);
if (p.IsFile()) return p; if (p.IsFile()) return p;
p = bp.Combine(id+".png"); p = bp.Combine(sid+".json");
if (p.IsFile()) return p;
p = bp.Combine(sid+".png");
if (p.IsFile()) return p; if (p.IsFile()) return p;
} }
// TBD - directly in romfs, or in an assets folder? // TBD - directly in romfs, or in an assets folder?
Path bp = Path("romfs:"); Path bp = Path("romfs:");
Path p = bp.Combine(id+".json"); Path p = bp.Combine(sid);
if (p.IsFile()) return p; if (p.IsFile()) return p;
p = bp.Combine(id+".png"); p = bp.Combine(sid+".json");
if (p.IsFile()) return p;
p = bp.Combine(sid+".png");
if (p.IsFile()) return p;
}
else if (pfx == "sdmc" || pfx == "romfs") {
Path p = Path(id);
if (p.IsFile()) return p;
p = Path(id + ".json");
if (p.IsFile()) return p;
p = Path(id + ".png");
if (p.IsFile()) return p; if (p.IsFile()) return p;
} }
else { else {
// theme asset; check in each theme from selected to most-fallback // theme asset; check in each theme from selected to most-fallback
for (auto thm : themeData) { for (auto thm : themeData) {
Path p = thm.basePath.Combine(id+".json"); Path p = thm.basePath.Combine(id);
if (p.IsFile()) return p;
p = thm.basePath.Combine(id+".json");
if (p.IsFile()) return p; if (p.IsFile()) return p;
p = thm.basePath.Combine(id+".png"); p = thm.basePath.Combine(id+".png");
if (p.IsFile()) return p; if (p.IsFile()) return p;

View File

@ -87,6 +87,17 @@ namespace starlight {
TextConfig(const std::string& fontName, Color text, Color border = Color::transparent); TextConfig(const std::string& fontName, Color text, Color border = Color::transparent);
~TextConfig() = default; ~TextConfig() = default;
TextConfig(const TextConfig& o) : textColor(o.textColor), borderColor(o.borderColor), justification(o.justification) { font = o.font; }
TextConfig(const TextConfig&& o) : textColor(o.textColor), borderColor(o.borderColor), justification(o.justification) { font = o.font; }
TextConfig& operator =(const TextConfig& o) {
font = o.font; textColor = o.textColor; borderColor = o.borderColor; justification = o.justification;
return *this;
}
TextConfig& operator =(const TextConfig&& o) {
font = o.font; textColor = o.textColor; borderColor = o.borderColor; justification = o.justification;
return *this;
}
void Print(Vector2 position, const std::string& text, Vector2 justification = Vector2::invalid); void Print(Vector2 position, const std::string& text, Vector2 justification = Vector2::invalid);
void Print(VRect rect, const std::string& text, Vector2 justification = Vector2::invalid); void Print(VRect rect, const std::string& text, Vector2 justification = Vector2::invalid);

View File

@ -18,6 +18,7 @@ namespace starlight {
std::shared_ptr<T> ptr = nullptr; std::shared_ptr<T> ptr = nullptr;
ThemeRefContainer* redir = nullptr; ThemeRefContainer* redir = nullptr;
unsigned int lastAccess = 0; // how many gc sweeps since last use unsigned int lastAccess = 0; // how many gc sweeps since last use
volatile int refCount = 0;
void Unload(bool full = false) { void Unload(bool full = false) {
ptr.reset(); ptr.reset();
if (full) redir = nullptr; if (full) redir = nullptr;
@ -54,12 +55,28 @@ namespace starlight {
class ThemeRef { class ThemeRef {
friend class starlight::ThemeManager; friend class starlight::ThemeManager;
protected: protected:
const ThemeRefContainer<T>* cptr; ThemeRefContainer<T>* cptr;
public: public:
ThemeRef() : cptr(nullptr) { } ThemeRef() : cptr(nullptr) { }
ThemeRef(ThemeRefContainer<T>* c) : cptr(c) { } ThemeRef(ThemeRefContainer<T>* c) : cptr(c) { if (cptr) cptr->refCount++; }
~ThemeRef() { } ThemeRef(ThemeRef<T>& o) : cptr(o.cptr) { if (cptr) cptr->refCount++; }
inline const ThemeRefContainer<T>& operator ->() const { return *cptr; } ThemeRef(ThemeRef<T>&& o) : cptr(o.cptr) { if (cptr) cptr->refCount++; }
~ThemeRef() { if (cptr) cptr->refCount--; }
ThemeRef<T>& operator =(const ThemeRef<T>& o) {
if (cptr) cptr->refCount--;
cptr = o.cptr;
if (cptr) cptr->refCount++;
return *this;
}
ThemeRef<T>& operator =(const ThemeRef<T>&& o) {
if (cptr) cptr->refCount--;
cptr = o.cptr;
if (cptr) cptr->refCount++;
return *this;
}
inline const ThemeRefContainer<T>& operator ->() const { return const_cast<const ThemeRefContainer<T>&>(*cptr); }
inline explicit operator bool() const { return cptr != nullptr; } inline explicit operator bool() const { return cptr != nullptr; }
inline std::shared_ptr<T> GetShared() const { return (*cptr).getptr(); } inline std::shared_ptr<T> GetShared() const { return (*cptr).getptr(); }
inline const std::string& GetName() const { return (*cptr).name; } inline const std::string& GetName() const { return (*cptr).name; }