Add new shared pointer and make use of it

This commit is contained in:
Gericom
2026-03-28 12:03:06 +01:00
parent bec797ffe7
commit 21a8790ebc
66 changed files with 1098 additions and 523 deletions

View File

@@ -28,7 +28,6 @@
#include "romBrowser/RomBrowserController.h" #include "romBrowser/RomBrowserController.h"
#include "DialogPresenter.h" #include "DialogPresenter.h"
#include "themes/ITheme.h" #include "themes/ITheme.h"
#include "core/SharedPtr.h"
#include "animation/Animator.h" #include "animation/Animator.h"
class alignas(32) App : public IProcess class alignas(32) App : public IProcess

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "core/SharedPtr.h"
#include "animation/Animator.h" #include "animation/Animator.h"
#include "gui/views/DialogView.h" #include "gui/views/DialogView.h"
@@ -49,7 +50,7 @@ public:
/// @brief Gets the focus that was stored when a dialog was opened. /// @brief Gets the focus that was stored when a dialog was opened.
/// @return The view that was focused when the current dialog was opened. /// @return The view that was focused when the current dialog was opened.
constexpr View* GetOldFocus() const constexpr SharedPtr<View> GetOldFocus() const
{ {
return _oldFocus; return _oldFocus;
} }
@@ -68,7 +69,7 @@ private:
std::unique_ptr<DialogView> _currentDialog; std::unique_ptr<DialogView> _currentDialog;
std::unique_ptr<DialogView> _nextDialog; std::unique_ptr<DialogView> _nextDialog;
bool _initVram = false; bool _initVram = false;
View* _oldFocus = nullptr; SharedPtr<View> _oldFocus = nullptr;
Animator<int> _scrimAnimator; Animator<int> _scrimAnimator;
Animator<int> _yAnimator; Animator<int> _yAnimator;
State _curState = State::Idle; State _curState = State::Idle;

View File

@@ -0,0 +1,35 @@
#include "common.h"
#include <libtwl/rtos/rtosIrq.h>
#include "AtomicSharedPtr.h"
void AtomicSharedPtrBase::Reset(void* newObject, RefCount* newRefCount, bool increaseNewRefCount)
{
u32 irq = rtos_disableIrqs(); // 1
auto refCount = _refCount;
_object = newObject;
_refCount = newRefCount;
if (increaseNewRefCount && _refCount)
{
_refCount->refCount++;
}
if (refCount && --refCount->refCount == 0) [[gnu::unlikely]]
{
refCount->weakRefCount++; // ensure the ref count is not destructed elsewhere
rtos_restoreIrqs(irq); // 1
refCount->DestructObject();
irq = rtos_disableIrqs(); // 2
if (--refCount->weakRefCount == 0) [[gnu::unlikely]]
{
rtos_restoreIrqs(irq); // 2
delete refCount;
}
else
{
rtos_restoreIrqs(irq); // 2
}
}
else
{
rtos_restoreIrqs(irq); // 1
}
}

View File

@@ -0,0 +1,134 @@
#pragma once
#include <type_traits>
#include <libtwl/rtos/rtosIrq.h>
#include "SharedPtr.h"
class AtomicSharedPtrBase
{
public:
void Reset()
{
Reset(nullptr, nullptr, false);
}
protected:
void* volatile _object;
RefCount* volatile _refCount;
AtomicSharedPtrBase()
: _object(nullptr), _refCount(nullptr) { }
AtomicSharedPtrBase(void* object, RefCount* refCount)
: _object(object), _refCount(refCount) { }
~AtomicSharedPtrBase()
{
Reset(nullptr, nullptr, false);
}
void Reset(void* newObject, RefCount* newRefCount, bool increaseNewRefCount);
};
template <class T>
class AtomicSharedPtr : public AtomicSharedPtrBase
{
public:
AtomicSharedPtr() { }
AtomicSharedPtr(std::nullptr_t) { }
AtomicSharedPtr(const SharedPtr<T>& sharedPtr)
: AtomicSharedPtrBase(sharedPtr._object, sharedPtr._refCount)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->refCount);
}
}
template <class Y> requires std::assignable_from<T*&, Y*>
AtomicSharedPtr(const SharedPtr<Y>& sharedPtr)
: AtomicSharedPtrBase(static_cast<T*>(sharedPtr.GetPointer()), sharedPtr._refCount)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->refCount);
}
}
template <class Y>
explicit AtomicSharedPtr(const SharedPtr<Y>& sharedPtr)
: AtomicSharedPtrBase(static_cast<T*>(sharedPtr.GetPointer()), sharedPtr._refCount)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->refCount);
}
}
AtomicSharedPtr(SharedPtr<T>&& sharedPtr)
: AtomicSharedPtrBase(sharedPtr._object, sharedPtr._refCount)
{
sharedPtr._object = nullptr;
sharedPtr._refCount = nullptr;
}
template <class Y> requires std::assignable_from<T*&, Y*>
AtomicSharedPtr(SharedPtr<Y>&& sharedPtr)
: AtomicSharedPtrBase(static_cast<T*>(sharedPtr.GetPointer()), sharedPtr._refCount)
{
sharedPtr._object = nullptr;
sharedPtr._refCount = nullptr;
}
template <class Y>
explicit AtomicSharedPtr(SharedPtr<Y>&& sharedPtr)
: AtomicSharedPtrBase(static_cast<T*>(sharedPtr.GetPointer()), sharedPtr._refCount)
{
sharedPtr._object = nullptr;
sharedPtr._refCount = nullptr;
}
AtomicSharedPtr& operator=(const SharedPtr<T>& sharedPtr)
{
Reset(sharedPtr._object, sharedPtr._refCount, true);
return *this;
}
template <class Y> requires std::assignable_from<T*&, Y*>
AtomicSharedPtr<T>& operator=(const SharedPtr<Y>& sharedPtr)
{
Reset(static_cast<T*>(sharedPtr.GetPointer()), sharedPtr._refCount, true);
return *this;
}
AtomicSharedPtr& operator=(SharedPtr<T>&& sharedPtr)
{
Reset(sharedPtr._object, sharedPtr._refCount, false);
sharedPtr._object = nullptr;
sharedPtr._refCount = nullptr;
return *this;
}
template <class Y> requires std::assignable_from<T*&, Y*>
AtomicSharedPtr<T>& operator=(SharedPtr<Y>&& sharedPtr)
{
Reset(static_cast<T*>(sharedPtr.GetPointer()), sharedPtr._refCount, false);
sharedPtr._object = nullptr;
sharedPtr._refCount = nullptr;
return *this;
}
SharedPtr<T> Lock() const
{
u32 irq = rtos_disableIrqs();
auto object = static_cast<T*>(_object);
auto refCount = _refCount;
if (refCount)
{
refCount->refCount++;
}
rtos_restoreIrqs(irq);
return SharedPtr<T>(object, refCount);
}
};

View File

@@ -0,0 +1,42 @@
#pragma once
#include "SharedPtr.h"
#include "WeakPtr.h"
class EnableSharedFromThisBase
{
template <class Y>
friend class SharedPtr;
template <class Y>
friend class EnableSharedFromThis;
private:
EnableSharedFromThisBase() = default;
};
template <class T>
class EnableSharedFromThis : public EnableSharedFromThisBase
{
template <class Y>
friend class SharedPtr;
protected:
SharedPtr<T> SharedFromThis()
{
return __sharedFromThisWeakPtr.Lock();
}
WeakPtr<T> WeakFromThis()
{
return __sharedFromThisWeakPtr;
}
private:
WeakPtr<T> __sharedFromThisWeakPtr;
template <class Y>
void __SetSharedFromThisWeakPtr(const SharedPtr<Y>& sharedPtr)
{
__sharedFromThisWeakPtr = WeakPtr<Y>(sharedPtr.GetPointer(), sharedPtr._refCount);
}
};

View File

@@ -0,0 +1,58 @@
#pragma once
#include <array>
extern "C" void shared_ptr_increase_ref_count(vu32& refCount);
class RefCount
{
public:
vu32 refCount;
vu32 weakRefCount;
virtual ~RefCount() = default;
virtual void DestructObject() = 0;
protected:
explicit RefCount()
: refCount(1), weakRefCount(0) { }
};
template <class T>
class StandaloneRefCount : public RefCount
{
public:
explicit StandaloneRefCount(T* object)
: _object(object) { }
void DestructObject() final
{
delete _object;
}
private:
T* _object;
};
template <class T>
class alignas(T) MakeSharedRefCount : public RefCount
{
public:
explicit MakeSharedRefCount(auto&&... args)
{
new (_object.data()) T(std::forward<decltype(args)>(args)...);
}
T* GetObject()
{
return reinterpret_cast<T*>(_object.data());
}
void DestructObject() final
{
reinterpret_cast<T*>(_object.data())->~T();
}
private:
std::array<u8, sizeof(T)> _object alignas(T);
};

View File

@@ -0,0 +1,31 @@
#include "common.h"
#include <libtwl/rtos/rtosIrq.h>
#include "SharedPtr.h"
void SharedPtrBase::ResetIntern()
{
auto refCount = _refCount;
_object = nullptr;
_refCount = nullptr;
u32 irq = rtos_disableIrqs(); // 1
if (--refCount->refCount == 0) [[gnu::unlikely]]
{
refCount->weakRefCount++; // ensure the ref count is not destructed elsewhere
rtos_restoreIrqs(irq); // 1
refCount->DestructObject();
irq = rtos_disableIrqs(); // 2
if (--refCount->weakRefCount == 0) [[gnu::unlikely]]
{
rtos_restoreIrqs(irq); // 2
delete refCount;
}
else
{
rtos_restoreIrqs(irq); // 2
}
}
else
{
rtos_restoreIrqs(irq); // 1
}
}

View File

@@ -1,163 +1,209 @@
#pragma once #pragma once
#include <type_traits>
#include "RefCount.h"
static inline u32 arm_getCpsr() class EnableSharedFromThisBase;
{
u32 cpsr;
asm volatile("mrs %0, cpsr" : "=r" (cpsr));
return cpsr;
}
static inline void arm_setCpsrControl(u32 cpsrControl)
{
asm volatile("msr cpsr_c, %0" :: "r" (cpsrControl) : "cc");
}
static inline u32 arm_disableIrqs(void)
{
u32 oldCpsr = arm_getCpsr();
arm_setCpsrControl(oldCpsr | 0x80);
return oldCpsr;
}
static inline void arm_restoreIrqs(u32 oldCpsr)
{
arm_setCpsrControl(oldCpsr);
}
template <class T> template <class T>
class SharedPtr class EnableSharedFromThis;
{
T* _pointer;
vu32* _refCount;
class SharedPtrBase
{
public: public:
SharedPtr() void Reset()
: _pointer(nullptr), _refCount(nullptr) { (void)sizeof(T); }
explicit SharedPtr(T* pointer)
: _pointer(pointer), _refCount(pointer ? new u32(1) : nullptr) { (void)sizeof(T); }
SharedPtr(const SharedPtr& other)
{ {
u32 irq = arm_disableIrqs(); if (_refCount != nullptr)
_pointer = other._pointer;
_refCount = other._refCount;
if (_pointer)
{ {
(*_refCount)++; ResetIntern();
} }
arm_restoreIrqs(irq);
} }
SharedPtr(SharedPtr&& other) protected:
: _pointer(other._pointer), _refCount(other._refCount) void* _object;
{ RefCount* _refCount;
other._pointer = nullptr;
other._refCount = nullptr;
}
~SharedPtr() SharedPtrBase()
: _object(nullptr), _refCount(nullptr) { }
SharedPtrBase(void* object, RefCount* refCount)
: _object(object), _refCount(refCount) { }
SharedPtrBase(const void* object, RefCount* refCount)
: _object((void*)object), _refCount(refCount) { }
~SharedPtrBase()
{ {
Reset(); Reset();
} }
[[gnu::noinline]] void ResetIntern();
};
template <class T>
class SharedPtr : public SharedPtrBase
{
template <class Y> friend class WeakPtr;
template <class Y> friend class SharedPtr;
template <class Y> friend class AtomicSharedPtr;
template <class Y> friend class EnableSharedFromThis;
public:
SharedPtr() { }
SharedPtr(std::nullptr_t) { }
explicit SharedPtr(T* object)
: SharedPtrBase(object, object == nullptr ? nullptr : new StandaloneRefCount<T>(object))
{
if (_object != nullptr)
{
if constexpr (std::is_convertible<T*, EnableSharedFromThisBase*>::value)
{
_refCount->weakRefCount = 1;
GetPointer()->__SetSharedFromThisWeakPtr(*this);
}
}
}
template <class Y> requires std::assignable_from<T*&, Y*>
explicit SharedPtr(Y* object)
: SharedPtrBase(static_cast<T*>(object), object == nullptr ? nullptr : new StandaloneRefCount<Y>(object))
{
if (object != nullptr)
{
if constexpr (std::is_convertible<Y*, EnableSharedFromThisBase*>::value)
{
_refCount->weakRefCount = 1;
GetPointer()->__SetSharedFromThisWeakPtr(*this);
}
}
}
SharedPtr(const SharedPtr& other)
: SharedPtrBase(other._object, other._refCount)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->refCount);
}
}
template <class Y> requires std::assignable_from<T*&, Y*>
SharedPtr(const SharedPtr<Y>& other)
: SharedPtrBase(static_cast<T*>(other.GetPointer()), other._refCount)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->refCount);
}
}
template <class Y>
explicit SharedPtr(const SharedPtr<Y>& other)
: SharedPtrBase(static_cast<T*>(other.GetPointer()), other._refCount)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->refCount);
}
}
SharedPtr(SharedPtr&& other)
: SharedPtrBase(other._object, other._refCount)
{
other._object = nullptr;
other._refCount = nullptr;
}
template <class Y> requires std::assignable_from<T*&, Y*>
SharedPtr(SharedPtr<Y>&& other)
: SharedPtrBase(static_cast<T*>(other.GetPointer()), other._refCount)
{
other._object = nullptr;
other._refCount = nullptr;
}
template <class Y>
explicit SharedPtr(SharedPtr<Y>&& other)
: SharedPtrBase(static_cast<T*>(other.GetPointer()), other._refCount)
{
other._object = nullptr;
other._refCount = nullptr;
}
static SharedPtr<T> MakeShared(auto&&... args)
{
auto refCount = new MakeSharedRefCount<T>(std::forward<decltype(args)>(args)...);
return SharedPtr<T>(refCount->GetObject(), refCount, true);
}
SharedPtr& operator=(const SharedPtr& other) SharedPtr& operator=(const SharedPtr& other)
{ {
u32 irq = arm_disableIrqs(); Reset();
T* pointer = _pointer; _object = other._object;
if (pointer)
{
vu32* refCount = _refCount;
u32 newValue = *refCount - 1;
*refCount = newValue;
_pointer = other._pointer;
_refCount = other._refCount; _refCount = other._refCount;
if (_pointer) if (_refCount)
{ {
(*_refCount)++; shared_ptr_increase_ref_count(_refCount->refCount);
} }
arm_restoreIrqs(irq); return *this;
if (newValue == 0) }
{
delete pointer; template <class Y> requires std::assignable_from<T*&, Y*>
delete refCount; SharedPtr<T>& operator=(const SharedPtr<Y>& other)
} {
} Reset();
else _object = static_cast<T*>(other.GetPointer());
{ _refCount = other._refCount;
_pointer = other._pointer; if (_refCount)
_refCount = other._refCount; {
if (_pointer) shared_ptr_increase_ref_count(_refCount->refCount);
{
(*_refCount)++;
}
arm_restoreIrqs(irq);
} }
return *this; return *this;
} }
[[gnu::noinline]]
SharedPtr& operator=(SharedPtr&& other) SharedPtr& operator=(SharedPtr&& other)
{ {
u32 irq = arm_disableIrqs(); Reset();
T* pointer = _pointer; _object = other._object;
if (pointer)
{
vu32* refCount = _refCount;
u32 newValue = *refCount - 1;
*refCount = newValue;
_pointer = other._pointer;
_refCount = other._refCount; _refCount = other._refCount;
other._pointer = nullptr; other._object = nullptr;
other._refCount = nullptr; other._refCount = nullptr;
arm_restoreIrqs(irq);
if (newValue == 0)
{
delete pointer;
delete refCount;
}
}
else
{
_pointer = other._pointer;
_refCount = other._refCount;
other._pointer = nullptr;
other._refCount = nullptr;
arm_restoreIrqs(irq);
}
return *this; return *this;
} }
[[gnu::noinline]] template <class Y> requires std::assignable_from<T*&, Y*>
void Reset() SharedPtr<T>& operator=(SharedPtr<Y>&& other)
{ {
u32 irq = arm_disableIrqs(); Reset();
T* pointer = _pointer; _object = static_cast<T*>(other.GetPointer());
if (pointer) _refCount = other._refCount;
{ other._object = nullptr;
vu32* refCount = _refCount; other._refCount = nullptr;
u32 newValue = *refCount - 1; return *this;
*refCount = newValue;
_pointer = nullptr;
_refCount = nullptr;
arm_restoreIrqs(irq);
if (newValue == 0)
{
delete pointer;
delete refCount;
}
}
else
{
arm_restoreIrqs(irq);
}
} }
constexpr T& operator*() const { return *_pointer; } T& operator*() const { return *static_cast<T*>(_object); }
constexpr T* operator->() const { return _pointer; } T* operator->() const { return static_cast<T*>(_object); }
T* GetPointer() const { return static_cast<T*>(_object); }
constexpr T* GetPointer() const { return _pointer; } bool IsValid() const { return _object != nullptr; }
constexpr u32 GetRefCount() const { return _refCount ? *_refCount : 0; } operator bool() const { return _object != nullptr; }
constexpr bool IsValid() const { return _pointer; }
private:
SharedPtr(T* object, RefCount* refCount)
: SharedPtrBase(object, refCount) { }
SharedPtr(T* object, RefCount* refCount, bool doSharedFromThis)
: SharedPtrBase(object, refCount)
{
if (doSharedFromThis)
{
if constexpr (std::is_convertible<T*, EnableSharedFromThisBase*>::value)
{
_refCount->weakRefCount = 1;
GetPointer()->__SetSharedFromThisWeakPtr(*this);
}
}
}
}; };

View File

@@ -0,0 +1,15 @@
.section .itcm
.arm
// r0 = &refCount
.global shared_ptr_increase_ref_count
.type shared_ptr_increase_ref_count, %function
shared_ptr_increase_ref_count:
mrs r2, cpsr
orr r1, r2, #0x80
msr cpsr_c, r1
ldr r12, [r0]
add r12, r12, #1
str r12, [r0]
msr cpsr_c, r2
bx lr

View File

@@ -0,0 +1,35 @@
#include "common.h"
#include <libtwl/rtos/rtosIrq.h>
#include "WeakPtr.h"
void WeakPtrBase::ResetIntern()
{
u32 irq = rtos_disableIrqs();
auto refCount = _refCount;
if (--refCount->weakRefCount == 0)
{
_refCount = nullptr;
rtos_restoreIrqs(irq);
delete refCount;
}
else
{
rtos_restoreIrqs(irq);
}
}
bool WeakPtrBase::LockIntern() const
{
u32 irq = rtos_disableIrqs();
if (_refCount->refCount != 0)
{
_refCount->refCount++;
rtos_restoreIrqs(irq);
return true;
}
else
{
rtos_restoreIrqs(irq);
return false;
}
}

158
arm9/source/core/WeakPtr.h Normal file
View File

@@ -0,0 +1,158 @@
#pragma once
#include <type_traits>
#include "RefCount.h"
#include "SharedPtr.h"
class WeakPtrBase
{
public:
~WeakPtrBase()
{
Reset();
}
void Reset()
{
if (_refCount)
{
Reset();
}
}
protected:
RefCount* _refCount;
WeakPtrBase()
: _refCount(nullptr) { }
explicit WeakPtrBase(RefCount* refCount)
: _refCount(refCount) { }
void ResetIntern();
bool LockIntern() const;
};
template <class T>
class WeakPtr : public WeakPtrBase
{
template <class Y> friend class WeakPtr;
template <class Y> friend class EnableSharedFromThis;
public:
WeakPtr() { }
WeakPtr(std::nullptr_t) { }
WeakPtr(const WeakPtr& other)
: WeakPtrBase(other._refCount), _object(other._object)
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->weakRefCount);
}
}
WeakPtr(WeakPtr&& other)
: WeakPtrBase(other._refCount), _object(other._object)
{
other._refCount = nullptr;
other._object = nullptr;
}
template <class Y> requires std::assignable_from<T*&, Y*>
WeakPtr(const SharedPtr<Y>& sharedPtr)
: WeakPtrBase(sharedPtr._refCount), _object(static_cast<T*>(sharedPtr.GetPointer()))
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->weakRefCount);
}
}
template <class Y>
explicit WeakPtr(const SharedPtr<Y>& sharedPtr)
: WeakPtrBase(sharedPtr._refCount), _object(static_cast<T*>(sharedPtr.GetPointer()))
{
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->weakRefCount);
}
}
WeakPtr& operator=(const WeakPtr& other)
{
Reset();
_object = other._object;
_refCount = other._refCount;
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->weakRefCount);
}
return *this;
}
template <class Y> requires std::assignable_from<T*&, Y*>
WeakPtr<T>& operator=(const WeakPtr<Y>& other)
{
Reset();
_object = static_cast<T*>(static_cast<Y*>(other._object));
_refCount = other._refCount;
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->weakRefCount);
}
return *this;
}
template <class Y> requires std::assignable_from<T*&, Y*>
WeakPtr<T>& operator=(const SharedPtr<Y>& sharedPtr)
{
Reset();
_object = static_cast<T*>(sharedPtr.GetPointer());
_refCount = sharedPtr._refCount;
if (_refCount)
{
shared_ptr_increase_ref_count(_refCount->weakRefCount);
}
return *this;
}
WeakPtr& operator=(WeakPtr&& other)
{
Reset();
_object = other._object;
_refCount = other._refCount;
other._object = nullptr;
other._refCount = nullptr;
return *this;
}
template <class Y> requires std::assignable_from<T*&, Y*>
WeakPtr<T>& operator=(WeakPtr<Y>&& other)
{
Reset();
_object = static_cast<T*>(static_cast<Y*>(other._object));
_refCount = other._refCount;
other._object = nullptr;
other._refCount = nullptr;
return *this;
}
SharedPtr<T> Lock() const
{
if (_refCount && LockIntern())
{
return SharedPtr<T>(_object, _refCount);
}
else
{
return SharedPtr<T>();
}
}
private:
T* _object;
WeakPtr(T* object, RefCount* refCount)
: WeakPtrBase(refCount), _object(object) { }
};

View File

@@ -3,7 +3,7 @@
#include "input/InputProvider.h" #include "input/InputProvider.h"
#include "FocusManager.h" #include "FocusManager.h"
void FocusManager::Focus(View* newFocus) void FocusManager::Focus(const SharedPtr<View>& newFocus)
{ {
if (!newFocus) if (!newFocus)
{ {
@@ -11,48 +11,71 @@ void FocusManager::Focus(View* newFocus)
return; return;
} }
if (_currentFocus) if (auto currentFocus = _currentFocus.Lock())
_currentFocus->SetFocused(false); {
currentFocus->SetFocused(false);
}
newFocus->SetFocused(true); newFocus->SetFocused(true);
_currentFocus = newFocus; _currentFocus = newFocus;
} }
void FocusManager::Unfocus() void FocusManager::Unfocus()
{ {
if (_currentFocus) if (auto currentFocus = _currentFocus.Lock())
_currentFocus->SetFocused(false); {
_currentFocus = nullptr; currentFocus->SetFocused(false);
}
_currentFocus.Reset();
} }
void FocusManager::Update(const InputProvider& inputProvider) void FocusManager::Update(const InputProvider& inputProvider)
{ {
if (!_currentFocus || !_currentFocus->GetParent()) auto currentFocus = _currentFocus.Lock();
if (!currentFocus || !currentFocus->GetParent())
return; // todo return; // todo
View* newFocus = nullptr; SharedPtr<View> newFocus;
if (inputProvider.Triggered(InputKey::DpadUp)) if (inputProvider.Triggered(InputKey::DpadUp))
newFocus = _currentFocus->GetParent()->MoveFocus(_currentFocus, FocusMoveDirection::Up, _currentFocus); {
newFocus = currentFocus->GetParent()->MoveFocus(currentFocus, FocusMoveDirection::Up, currentFocus.GetPointer());
}
else if (inputProvider.Triggered(InputKey::DpadDown)) else if (inputProvider.Triggered(InputKey::DpadDown))
newFocus = _currentFocus->GetParent()->MoveFocus(_currentFocus, FocusMoveDirection::Down, _currentFocus); {
newFocus = currentFocus->GetParent()->MoveFocus(currentFocus, FocusMoveDirection::Down, currentFocus.GetPointer());
}
else if (inputProvider.Triggered(InputKey::DpadLeft)) else if (inputProvider.Triggered(InputKey::DpadLeft))
newFocus = _currentFocus->GetParent()->MoveFocus(_currentFocus, FocusMoveDirection::Left, _currentFocus); {
newFocus = currentFocus->GetParent()->MoveFocus(currentFocus, FocusMoveDirection::Left, currentFocus.GetPointer());
}
else if (inputProvider.Triggered(InputKey::DpadRight)) else if (inputProvider.Triggered(InputKey::DpadRight))
newFocus = _currentFocus->GetParent()->MoveFocus(_currentFocus, FocusMoveDirection::Right, _currentFocus); {
newFocus = currentFocus->GetParent()->MoveFocus(currentFocus, FocusMoveDirection::Right, currentFocus.GetPointer());
}
else else
_currentFocus->HandleInput(inputProvider, *this); {
currentFocus->HandleInput(inputProvider, *this);
}
if (newFocus) if (newFocus)
{
Focus(newFocus); Focus(newFocus);
} }
}
bool FocusManager::IsFocusInside(const View* view) const bool FocusManager::IsFocusInside(const View* view) const
{ {
auto focusView = _currentFocus; if (auto currentFocus = _currentFocus.Lock())
{
auto focusView = currentFocus.GetPointer();
while (focusView) while (focusView)
{ {
if (view == focusView) if (view == focusView)
{
return true; return true;
}
focusView = focusView->GetParent(); focusView = focusView->GetParent();
} }
}
return false; return false;
} }

View File

@@ -1,4 +1,6 @@
#pragma once #pragma once
#include <core/SharedPtr.h>
#include <core/WeakPtr.h>
class View; class View;
class InputProvider; class InputProvider;
@@ -9,7 +11,7 @@ class FocusManager
public: public:
/// @brief Focuses the given view. /// @brief Focuses the given view.
/// @param newFocus The view to focus. /// @param newFocus The view to focus.
void Focus(View* newFocus); void Focus(const SharedPtr<View>& newFocus);
/// @brief Clears the current focus. /// @brief Clears the current focus.
void Unfocus(); void Unfocus();
@@ -20,7 +22,7 @@ public:
/// @brief Gets the currently focused view. /// @brief Gets the currently focused view.
/// @return A pointer to the view that is currently focused, or null if none. /// @return A pointer to the view that is currently focused, or null if none.
constexpr View* GetCurrentFocus() const { return _currentFocus; } constexpr SharedPtr<View> GetCurrentFocus() const { return _currentFocus.Lock(); }
/// @brief Checks whether the current focus lies inside the given view. /// @brief Checks whether the current focus lies inside the given view.
/// @param view The view to check for. /// @param view The view to check for.
@@ -28,5 +30,5 @@ public:
bool IsFocusInside(const View* view) const; bool IsFocusInside(const View* view) const;
private: private:
View* _currentFocus = nullptr; WeakPtr<View> _currentFocus;
}; };

View File

@@ -20,19 +20,15 @@ public:
/// @brief Creates and returns a view for this adapter. /// @brief Creates and returns a view for this adapter.
/// @return The created view. /// @return The created view.
virtual View* CreateView() const = 0; virtual SharedPtr<View> CreateView() const = 0;
/// @brief Destroys a \p view for this adapter that was previously created with CreateView.
/// @param view The view to destroy.
virtual void DestroyView(View* view) const = 0;
/// @brief Binds the given \p view to the item at the given \p index. /// @brief Binds the given \p view to the item at the given \p index.
/// @param view The view to bind. /// @param view The view to bind.
/// @param index The item index to bind to. /// @param index The item index to bind to.
virtual void BindView(View* view, int index) const = 0; virtual void BindView(SharedPtr<View> view, int index) const = 0;
/// @brief Releases a \p view that was previously bound with BindView, such that it can be reused. /// @brief Releases a \p view that was previously bound with BindView, such that it can be reused.
/// @param view The view to release. /// @param view The view to release.
/// @param index The item index that was bound to the view. /// @param index The item index that was bound to the view.
virtual void ReleaseView(View* view, int index) const = 0; virtual void ReleaseView(SharedPtr<View> view, int index) const = 0;
}; };

View File

@@ -4,7 +4,7 @@
#include "gui/input/InputProvider.h" #include "gui/input/InputProvider.h"
#include "RecyclerView.h" #include "RecyclerView.h"
RecyclerView::RecyclerView(int x, int y, int width, int height, Mode mode) RecyclerView::RecyclerView(Private, int x, int y, int width, int height, Mode mode)
: _width(width), _height(height), _mode(mode), _rows(0), _columns(0) : _width(width), _height(height), _mode(mode), _rows(0), _columns(0)
, _viewPoolFreeCount(0), _viewPoolTotalCount(0) , _viewPoolFreeCount(0), _viewPoolTotalCount(0)
, _xOffset(0), _yOffset(0), _xPadding(0), _yPadding(0) , _xOffset(0), _yOffset(0), _xPadding(0), _yPadding(0)
@@ -20,21 +20,21 @@ RecyclerView::~RecyclerView()
{ {
if (_adapter) if (_adapter)
{ {
for (u32 i = 0; i < _viewPoolTotalCount; i++) for (u32 i = _viewPoolFreeCount; i < _viewPoolTotalCount; i++)
{ {
_adapter->DestroyView(_viewPool[i].view); _adapter->ReleaseView(_viewPool[i].view, _viewPool[i].itemIdx);
} }
} }
} }
void RecyclerView::SetAdapter(const RecyclerAdapter* adapter, int initialSelectedIndex) void RecyclerView::SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex)
{ {
if (_adapter) if (_adapter)
{ {
_selectedItem = nullptr; _selectedItem = nullptr;
for (u32 i = 0; i < _viewPoolTotalCount; i++) for (u32 i = _viewPoolFreeCount; i < _viewPoolTotalCount; i++)
{ {
_adapter->DestroyView(_viewPool[i].view); _adapter->ReleaseView(_viewPool[i].view, _viewPool[i].itemIdx);
} }
_viewPool.reset(); _viewPool.reset();
_viewPoolFreeCount = 0; _viewPoolFreeCount = 0;
@@ -44,7 +44,7 @@ void RecyclerView::SetAdapter(const RecyclerAdapter* adapter, int initialSelecte
_curRangeStart = 0; _curRangeStart = 0;
_curRangeLength = 0; _curRangeLength = 0;
} }
_adapter = adapter; _adapter = std::move(adapter);
_adapter->GetViewSize(_itemWidth, _itemHeight); _adapter->GetViewSize(_itemWidth, _itemHeight);
_itemCount = _adapter->GetItemCount(); _itemCount = _adapter->GetItemCount();
if (_mode == Mode::HorizontalList || _mode == Mode::HorizontalGrid) if (_mode == Mode::HorizontalList || _mode == Mode::HorizontalGrid)
@@ -178,7 +178,7 @@ void RecyclerView::VBlank()
} }
} }
View* RecyclerView::MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> RecyclerView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (_itemCount == 0) if (_itemCount == 0)
{ {
@@ -195,9 +195,9 @@ View* RecyclerView::MoveFocus(View* currentFocus, FocusMoveDirection direction,
} }
} }
View* RecyclerView::MoveFocusHorizontal(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> RecyclerView::MoveFocusHorizontal(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (!_selectedItem || currentFocus != _selectedItem->view) if (!_selectedItem || currentFocus.GetPointer() != _selectedItem->view.GetPointer())
{ {
// incoming focus // incoming focus
if (direction != FocusMoveDirection::Down) if (direction != FocusMoveDirection::Down)
@@ -207,7 +207,7 @@ View* RecyclerView::MoveFocusHorizontal(View* currentFocus, FocusMoveDirection d
int idx = (-_xOffset + currentFocus->GetPosition().x - _xPadding + ((_xSpacing + _itemWidth) >> 1)) / (_xSpacing + _itemWidth) * _rows; int idx = (-_xOffset + currentFocus->GetPosition().x - _xPadding + ((_xSpacing + _itemWidth) >> 1)) / (_xSpacing + _itemWidth) * _rows;
SetSelectedItem(std::clamp(idx, 0, ((int)_itemCount - 1) / _rows * _rows)); SetSelectedItem(std::clamp(idx, 0, ((int)_itemCount - 1) / _rows * _rows));
return _selectedItem != nullptr ? _selectedItem->view : this; return _selectedItem != nullptr ? _selectedItem->view : SharedFromThis();
} }
int row = _selectedItem->itemIdx % _rows; int row = _selectedItem->itemIdx % _rows;
@@ -248,12 +248,12 @@ View* RecyclerView::MoveFocusHorizontal(View* currentFocus, FocusMoveDirection d
SetSelectedItem(std::clamp(idx, 0, (int)_itemCount - 1)); SetSelectedItem(std::clamp(idx, 0, (int)_itemCount - 1));
} }
return _selectedItem != nullptr ? _selectedItem->view : this; return _selectedItem != nullptr ? _selectedItem->view : SharedFromThis();
} }
View* RecyclerView::MoveFocusVertical(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> RecyclerView::MoveFocusVertical(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (!_selectedItem || currentFocus != _selectedItem->view) if (!_selectedItem || currentFocus.GetPointer() != _selectedItem->view.GetPointer())
{ {
// incoming focus // incoming focus
if (direction != FocusMoveDirection::Right) if (direction != FocusMoveDirection::Right)
@@ -263,7 +263,7 @@ View* RecyclerView::MoveFocusVertical(View* currentFocus, FocusMoveDirection dir
int idx = (-_yOffset + currentFocus->GetPosition().y - _yPadding + ((_ySpacing + _itemHeight) >> 1)) / (_ySpacing + _itemHeight) * _columns; int idx = (-_yOffset + currentFocus->GetPosition().y - _yPadding + ((_ySpacing + _itemHeight) >> 1)) / (_ySpacing + _itemHeight) * _columns;
SetSelectedItem(std::clamp(idx, 0, ((int)_itemCount - 1) / _columns * _columns)); SetSelectedItem(std::clamp(idx, 0, ((int)_itemCount - 1) / _columns * _columns));
return _selectedItem != nullptr ? _selectedItem->view : this; return _selectedItem != nullptr ? _selectedItem->view : SharedFromThis();
} }
int column = _selectedItem->itemIdx % _columns; int column = _selectedItem->itemIdx % _columns;
@@ -304,7 +304,7 @@ View* RecyclerView::MoveFocusVertical(View* currentFocus, FocusMoveDirection dir
SetSelectedItem(std::clamp(idx, 0, (int)_itemCount - 1)); SetSelectedItem(std::clamp(idx, 0, (int)_itemCount - 1));
} }
return _selectedItem != nullptr ? _selectedItem->view : this; return _selectedItem != nullptr ? _selectedItem->view : SharedFromThis();
} }
bool RecyclerView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) bool RecyclerView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)

View File

@@ -1,13 +1,16 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "core/EnableSharedFromThis.h"
#include "View.h" #include "View.h"
#include "RecyclerAdapter.h" #include "RecyclerAdapter.h"
#include "gui/FocusManager.h" #include "gui/FocusManager.h"
#include "animation/Animator.h" #include "animation/Animator.h"
#include "RecyclerViewBase.h" #include "RecyclerViewBase.h"
class RecyclerView : public RecyclerViewBase class RecyclerView : public RecyclerViewBase, public EnableSharedFromThis<RecyclerView>
{ {
struct Private { explicit Private() = default; };
public: public:
enum class Mode enum class Mode
{ {
@@ -21,10 +24,16 @@ public:
VerticalGrid VerticalGrid
}; };
RecyclerView(int x, int y, int width, int height, Mode mode); RecyclerView(Private, int x, int y, int width, int height, Mode mode);
static SharedPtr<RecyclerView> CreateShared(int x, int y, int width, int height, Mode mode)
{
return SharedPtr<RecyclerView>::MakeShared(Private(), x, y, width, height, mode);
}
~RecyclerView(); ~RecyclerView();
void SetAdapter(const RecyclerAdapter* adapter, int initialSelectedIndex = 0) override; void SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex = 0) override;
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
void Update() override; void Update() override;
void Draw(GraphicsContext& graphicsContext) override; void Draw(GraphicsContext& graphicsContext) override;
@@ -35,16 +44,20 @@ public:
return Rectangle(_position, _width, _height); return Rectangle(_position, _width, _height);
} }
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override; SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override; bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void Focus(FocusManager& focusManager) override void Focus(FocusManager& focusManager) override
{ {
if (_selectedItem) if (_selectedItem)
{
focusManager.Focus(_selectedItem->view); focusManager.Focus(_selectedItem->view);
}
else else
focusManager.Focus(this); {
focusManager.Focus(SharedFromThis());
}
} }
int GetSelectedItem() const override int GetSelectedItem() const override
@@ -69,7 +82,7 @@ public:
private: private:
struct ViewPoolEntry struct ViewPoolEntry
{ {
View* view; SharedPtr<View> view;
int itemIdx; int itemIdx;
}; };
@@ -107,6 +120,6 @@ private:
void EnsureVisible(int itemIdx, bool animate); void EnsureVisible(int itemIdx, bool animate);
Point GetItemPosition(int itemIdx); Point GetItemPosition(int itemIdx);
View* MoveFocusHorizontal(View* currentFocus, FocusMoveDirection direction, View* source); SharedPtr<View> MoveFocusHorizontal(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source);
View* MoveFocusVertical(View* currentFocus, FocusMoveDirection direction, View* source); SharedPtr<View> MoveFocusVertical(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source);
}; };

View File

@@ -2,16 +2,17 @@
#include "View.h" #include "View.h"
#include "RecyclerAdapter.h" #include "RecyclerAdapter.h"
#include "gui/FocusManager.h" #include "gui/FocusManager.h"
#include "core/SharedPtr.h"
/// @brief Abstract base class for a recycler view that displays a possibly large collection of items /// @brief Abstract base class for a recycler view that displays a possibly large collection of items
/// provided by an adapter in an efficient way. /// provided by an adapter in an efficient way.
class RecyclerViewBase : public View class RecyclerViewBase : public View
{ {
public: public:
virtual void SetAdapter(const RecyclerAdapter* adapter, int initialSelectedIndex = 0) = 0; virtual void SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex = 0) = 0;
virtual void Focus(FocusManager& focusManager) = 0; virtual void Focus(FocusManager& focusManager) = 0;
virtual int GetSelectedItem() const = 0; virtual int GetSelectedItem() const = 0;
protected: protected:
const RecyclerAdapter* _adapter = nullptr; SharedPtr<const RecyclerAdapter> _adapter;
}; };

View File

@@ -2,6 +2,7 @@
#include "core/LinkedListLink.h" #include "core/LinkedListLink.h"
#include "core/math/Point.h" #include "core/math/Point.h"
#include "core/math/Rectangle.h" #include "core/math/Rectangle.h"
#include "core/SharedPtr.h"
#include "../FocusManager.h" #include "../FocusManager.h"
#include "../FocusMoveDirection.h" #include "../FocusMoveDirection.h"
@@ -37,7 +38,7 @@ public:
/// @param direction The direction to move the focus in. /// @param direction The direction to move the focus in.
/// @param source The view that requested this view to move focus. /// @param source The view that requested this view to move focus.
/// @return The newly focused view, or null if the focus didn't change. /// @return The newly focused view, or null if the focus didn't change.
virtual View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) virtual SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (_parent && _parent != source) if (_parent && _parent != source)
return _parent->MoveFocus(currentFocus, direction, this); return _parent->MoveFocus(currentFocus, direction, this);

View File

@@ -11,27 +11,22 @@ void BannerListFileRecyclerAdapter::GetViewSize(int& width, int& height) const
height = 44; height = 44;
} }
View* BannerListFileRecyclerAdapter::CreateView() const SharedPtr<View> BannerListFileRecyclerAdapter::CreateView() const
{ {
return _romBrowserViewFactory->CreateBannerListItemView(_vblankTextureLoader); return _romBrowserViewFactory->CreateBannerListItemView(_vblankTextureLoader);
} }
void BannerListFileRecyclerAdapter::DestroyView(View* view) const void BannerListFileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
{ {
delete static_cast<BannerListItemView*>(view); auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
}
void BannerListFileRecyclerAdapter::BindView(View* view, int index) const
{
auto listItemView = static_cast<BannerListItemView*>(view);
listItemView->SetGraphics(_bannerListItemViewGraphics); listItemView->SetGraphics(_bannerListItemViewGraphics);
FileRecyclerAdapter::BindView(view, index); FileRecyclerAdapter::BindView(view, index);
} }
TaskResult<void> BannerListFileRecyclerAdapter::BindView(View* view, int index, TaskResult<void> BannerListFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
{ {
auto listItemView = static_cast<BannerListItemView*>(view); auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
const auto& fileInfo = _fileInfoManager->GetItem(index); const auto& fileInfo = _fileInfoManager->GetItem(index);
bool fileNameAsTitle = true; bool fileNameAsTitle = true;
if (internalFileInfo) if (internalFileInfo)
@@ -70,10 +65,10 @@ TaskResult<void> BannerListFileRecyclerAdapter::BindView(View* view, int index,
return TaskResult<void>::Completed(); return TaskResult<void>::Completed();
} }
void BannerListFileRecyclerAdapter::ReleaseView(View* view, int index) const void BannerListFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
{ {
LOG_DEBUG("Releasing %d\n", index); LOG_DEBUG("Releasing %d\n", index);
auto listItemView = static_cast<BannerListItemView*>(view); auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
listItemView->SetIcon(nullptr); listItemView->SetIcon(nullptr);
listItemView->SetGameTitle(u""); listItemView->SetGameTitle(u"");
_fileInfoManager->ReleaseFileInfo(index); _fileInfoManager->ReleaseFileInfo(index);

View File

@@ -17,10 +17,9 @@ public:
, _vblankTextureLoader(vblankTextureLoader) { } , _vblankTextureLoader(vblankTextureLoader) { }
void GetViewSize(int& width, int& height) const override; void GetViewSize(int& width, int& height) const override;
View* CreateView() const override; SharedPtr<View> CreateView() const override;
void DestroyView(View* view) const override; void BindView(SharedPtr<View> view, int index) const override;
void BindView(View* view, int index) const override; void ReleaseView(SharedPtr<View> view, int index) const override;
void ReleaseView(View* view, int index) const override;
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
@@ -29,6 +28,6 @@ private:
BannerListItemView::VramToken _bannerListItemViewGraphics; BannerListItemView::VramToken _bannerListItemViewGraphics;
VBlankTextureLoader* _vblankTextureLoader; VBlankTextureLoader* _vblankTextureLoader;
TaskResult<void> BindView(View* view, int index, TaskResult<void> BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override; const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
}; };

View File

@@ -13,21 +13,15 @@ void CoverFlowFileRecyclerAdapter::GetViewSize(int& width, int& height) const
height = 44; height = 44;
} }
View* CoverFlowFileRecyclerAdapter::CreateView() const SharedPtr<View> CoverFlowFileRecyclerAdapter::CreateView() const
{ {
return new CoverView(_vblankTextureLoader); return SharedPtr<CoverView>::MakeShared(_vblankTextureLoader);
} }
void CoverFlowFileRecyclerAdapter::DestroyView(View* view) const TaskResult<void> CoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
{
auto coverView = static_cast<CoverView*>(view);
delete coverView;
}
TaskResult<void> CoverFlowFileRecyclerAdapter::BindView(View* view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
{ {
auto coverView = static_cast<CoverView*>(view); auto coverView = static_cast<CoverView*>(view.GetPointer());
auto cover = _fileInfoManager->GetFileCover(index); auto cover = _fileInfoManager->GetFileCover(index);
if (cancelRequested) if (cancelRequested)
{ {
@@ -45,10 +39,10 @@ TaskResult<void> CoverFlowFileRecyclerAdapter::BindView(View* view, int index,
return TaskResult<void>::Completed(); return TaskResult<void>::Completed();
} }
void CoverFlowFileRecyclerAdapter::ReleaseView(View* view, int index) const void CoverFlowFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
{ {
LOG_DEBUG("Releasing %d\n", index); LOG_DEBUG("Releasing %d\n", index);
auto coverView = static_cast<CoverView*>(view); auto coverView = static_cast<CoverView*>(view.GetPointer());
coverView->ClearCover(); coverView->ClearCover();
_fileInfoManager->ReleaseFileInfo(index); _fileInfoManager->ReleaseFileInfo(index);
} }

View File

@@ -19,9 +19,8 @@ public:
, _coverRepository(coverRepository) { } , _coverRepository(coverRepository) { }
void GetViewSize(int& width, int& height) const override; void GetViewSize(int& width, int& height) const override;
View* CreateView() const override; SharedPtr<View> CreateView() const override;
void DestroyView(View* view) const override; void ReleaseView(SharedPtr<View> view, int index) const override;
void ReleaseView(View* view, int index) const override;
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
@@ -30,6 +29,6 @@ private:
VBlankTextureLoader* _vblankTextureLoader; VBlankTextureLoader* _vblankTextureLoader;
const ICoverRepository* _coverRepository; const ICoverRepository* _coverRepository;
TaskResult<void> BindView(View* view, int index, TaskResult<void> BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override; const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
}; };

View File

@@ -11,27 +11,22 @@ void IconGridFileRecyclerAdapter::GetViewSize(int& width, int& height) const
height = 44; height = 44;
} }
View* IconGridFileRecyclerAdapter::CreateView() const SharedPtr<View> IconGridFileRecyclerAdapter::CreateView() const
{ {
return _romBrowserViewFactory->CreateIconGridItemView(); return _romBrowserViewFactory->CreateIconGridItemView();
} }
void IconGridFileRecyclerAdapter::DestroyView(View* view) const void IconGridFileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
{ {
delete static_cast<IconGridItemView*>(view); auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
}
void IconGridFileRecyclerAdapter::BindView(View* view, int index) const
{
auto iconGridItemView = static_cast<IconGridItemView*>(view);
iconGridItemView->SetGraphics(_iconGridItemViewGraphics); iconGridItemView->SetGraphics(_iconGridItemViewGraphics);
FileRecyclerAdapter::BindView(view, index); FileRecyclerAdapter::BindView(view, index);
} }
TaskResult<void> IconGridFileRecyclerAdapter::BindView(View* view, int index, TaskResult<void> IconGridFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
{ {
auto iconGridItemView = static_cast<IconGridItemView*>(view); auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
auto icon = internalFileInfo ? internalFileInfo->CreateGameIcon() : nullptr; auto icon = internalFileInfo ? internalFileInfo->CreateGameIcon() : nullptr;
if (!icon) if (!icon)
{ {
@@ -59,10 +54,10 @@ TaskResult<void> IconGridFileRecyclerAdapter::BindView(View* view, int index,
return TaskResult<void>::Completed(); return TaskResult<void>::Completed();
} }
void IconGridFileRecyclerAdapter::ReleaseView(View* view, int index) const void IconGridFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
{ {
LOG_DEBUG("Releasing %d\n", index); LOG_DEBUG("Releasing %d\n", index);
auto iconGridItemView = static_cast<IconGridItemView*>(view); auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
iconGridItemView->SetIcon(nullptr); iconGridItemView->SetIcon(nullptr);
_fileInfoManager->ReleaseFileInfo(index); _fileInfoManager->ReleaseFileInfo(index);
} }

View File

@@ -14,10 +14,9 @@ public:
, _romBrowserViewFactory(romBrowserViewFactory) { } , _romBrowserViewFactory(romBrowserViewFactory) { }
void GetViewSize(int& width, int& height) const override; void GetViewSize(int& width, int& height) const override;
View* CreateView() const override; SharedPtr<View> CreateView() const override;
void DestroyView(View* view) const override; void BindView(SharedPtr<View> view, int index) const override;
void BindView(View* view, int index) const override; void ReleaseView(SharedPtr<View> view, int index) const override;
void ReleaseView(View* view, int index) const override;
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
@@ -25,6 +24,6 @@ private:
const IRomBrowserViewFactory* _romBrowserViewFactory; const IRomBrowserViewFactory* _romBrowserViewFactory;
IconGridItemView::VramToken _iconGridItemViewGraphics; IconGridItemView::VramToken _iconGridItemViewGraphics;
TaskResult<void> BindView(View* view, int index, TaskResult<void> BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override; const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
}; };

View File

@@ -17,19 +17,19 @@ public:
AppBarView::Orientation::Vertical, startButtonCount, endButtonCount); AppBarView::Orientation::Vertical, startButtonCount, endButtonCount);
} }
std::unique_ptr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override
{ {
auto recyclerView = std::make_unique<RecyclerView>(42, 0, 256 - 42, 192, RecyclerView::Mode::VerticalList); auto recyclerView = RecyclerView::CreateShared(42, 0, 256 - 42, 192, RecyclerView::Mode::VerticalList);
recyclerView->SetPadding(0, 3); recyclerView->SetPadding(0, 3);
recyclerView->SetItemSpacing(0, 3); recyclerView->SetItemSpacing(0, 3);
return recyclerView; return recyclerView;
} }
FileRecyclerAdapter* CreateRecyclerAdapter( SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new BannerListFileRecyclerAdapter( return SharedPtr<BannerListFileRecyclerAdapter>::MakeShared(
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), themeFileIconFactory, &viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), themeFileIconFactory,
romBrowserViewFactory, vblankTextureLoader); romBrowserViewFactory, vblankTextureLoader);
} }

View File

@@ -16,8 +16,8 @@ public:
virtual bool ShowCoverOnTopScreen() const { return true; } virtual bool ShowCoverOnTopScreen() const { return true; }
virtual std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory, virtual std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
int startButtonCount, int endButtonCount) const = 0; int startButtonCount, int endButtonCount) const = 0;
virtual std::unique_ptr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const = 0; virtual SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const = 0;
virtual FileRecyclerAdapter* CreateRecyclerAdapter( virtual SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const = 0; const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const = 0;
}; };

View File

@@ -16,12 +16,12 @@ public:
AppBarView::Orientation::Horizontal, startButtonCount, endButtonCount); AppBarView::Orientation::Horizontal, startButtonCount, endButtonCount);
} }
std::unique_ptr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override
{ {
return romBrowserViewFactory->CreateCoverFlowRecyclerView(); return romBrowserViewFactory->CreateCoverFlowRecyclerView();
} }
FileRecyclerAdapter* CreateRecyclerAdapter( SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
{ {

View File

@@ -17,19 +17,19 @@ public:
AppBarView::Orientation::Horizontal, startButtonCount, endButtonCount); AppBarView::Orientation::Horizontal, startButtonCount, endButtonCount);
} }
std::unique_ptr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override
{ {
auto recyclerView = std::make_unique<RecyclerView>(0, 42, 256, 192 - 42, RecyclerView::Mode::HorizontalGrid); auto recyclerView = RecyclerView::CreateShared(0, 42, 256, 192 - 42, RecyclerView::Mode::HorizontalGrid);
recyclerView->SetPadding(10, 0); recyclerView->SetPadding(10, 0);
recyclerView->SetItemSpacing(4, 4); recyclerView->SetItemSpacing(4, 4);
return recyclerView; return recyclerView;
} }
FileRecyclerAdapter* CreateRecyclerAdapter( SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new IconGridFileRecyclerAdapter( return SharedPtr<IconGridFileRecyclerAdapter>::MakeShared(
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), &viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
themeFileIconFactory, romBrowserViewFactory); themeFileIconFactory, romBrowserViewFactory);
} }

View File

@@ -17,19 +17,19 @@ public:
AppBarView::Orientation::Vertical, startButtonCount, endButtonCount); AppBarView::Orientation::Vertical, startButtonCount, endButtonCount);
} }
std::unique_ptr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const override
{ {
auto recyclerView = std::make_unique<RecyclerView>(42, 0, 256 - 42, 192, RecyclerView::Mode::VerticalGrid); auto recyclerView = RecyclerView::CreateShared(42, 0, 256 - 42, 192, RecyclerView::Mode::VerticalGrid);
recyclerView->SetPadding(0, 3); recyclerView->SetPadding(0, 3);
recyclerView->SetItemSpacing(9, 3); recyclerView->SetItemSpacing(9, 3);
return recyclerView; return recyclerView;
} }
FileRecyclerAdapter* CreateRecyclerAdapter( SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new IconGridFileRecyclerAdapter( return SharedPtr<IconGridFileRecyclerAdapter>::MakeShared(
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), &viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
themeFileIconFactory, romBrowserViewFactory); themeFileIconFactory, romBrowserViewFactory);
} }

View File

@@ -15,6 +15,34 @@ FileInfoManager::~FileInfoManager()
} }
} }
void FileInfoManager::LoadFileInfo(int index)
{
auto internalFileInfo = _extraFileInfo[index].internalFileInfo;
if (!internalFileInfo)
{
internalFileInfo = _items[index]->CreateInternalFileInfo();
}
if (!_extraFileInfo[index].fileCover.Lock())
{
_extraFileInfo[index].fileCover = SharedPtr(_coverRepository.GetCoverForFile(*_items[index], internalFileInfo));
}
_extraFileInfo[index].internalFileInfo = internalFileInfo;
}
void FileInfoManager::ReleaseFileInfo(int index)
{
auto internalFileInfo = _extraFileInfo[index].internalFileInfo;
if (internalFileInfo)
{
_extraFileInfo[index].internalFileInfo = nullptr;
delete internalFileInfo;
}
_extraFileInfo[index].fileCover.Reset();
}
int FileInfoManager::GetItemIndex(const char* fileName) int FileInfoManager::GetItemIndex(const char* fileName)
{ {
if (fileName == nullptr) if (fileName == nullptr)

View File

@@ -4,7 +4,7 @@
#include "FileInfo.h" #include "FileInfo.h"
#include "FileType/FileCover.h" #include "FileType/FileCover.h"
#include "ICoverRepository.h" #include "ICoverRepository.h"
#include "core/SharedPtr.h" #include "core/AtomicSharedPtr.h"
#include "FileType/InternalFileInfo.h" #include "FileType/InternalFileInfo.h"
class FileInfoManager class FileInfoManager
@@ -20,36 +20,12 @@ public:
SharedPtr<FileCover> GetFileCover(int index) SharedPtr<FileCover> GetFileCover(int index)
{ {
return _extraFileInfo[index].fileCover; return _extraFileInfo[index].fileCover.Lock();
} }
void LoadFileInfo(int index) void LoadFileInfo(int index);
{
auto internalFileInfo = GetInternalFileInfo(index);
if (!internalFileInfo)
{
internalFileInfo = _items[index]->CreateInternalFileInfo();
}
if (!_extraFileInfo[index].fileCover.IsValid()) void ReleaseFileInfo(int index);
{
_extraFileInfo[index].fileCover = SharedPtr(_coverRepository.GetCoverForFile(*_items[index], internalFileInfo));
}
_extraFileInfo[index].internalFileInfo = internalFileInfo;
}
void ReleaseFileInfo(int index)
{
auto internalFileInfo = GetInternalFileInfo(index);
if (internalFileInfo)
{
delete internalFileInfo;
_extraFileInfo[index].internalFileInfo = nullptr;
}
_extraFileInfo[index].fileCover.Reset();
}
int GetItemIndex(const char* fileName); int GetItemIndex(const char* fileName);
@@ -60,7 +36,7 @@ private:
struct ExtraFileInfo struct ExtraFileInfo
{ {
const InternalFileInfo* internalFileInfo; const InternalFileInfo* internalFileInfo;
SharedPtr<FileCover> fileCover; AtomicSharedPtr<FileCover> fileCover;
}; };
std::unique_ptr<const FileInfo*[]> _items; std::unique_ptr<const FileInfo*[]> _items;

View File

@@ -8,7 +8,7 @@ u32 FileRecyclerAdapter::GetItemCount() const
return _fileInfoManager->GetItemCount(); return _fileInfoManager->GetItemCount();
} }
void FileRecyclerAdapter::BindView(View* view, int index) const void FileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
{ {
LOG_DEBUG("Binding %d\n", index); LOG_DEBUG("Binding %d\n", index);
_taskQueue->Enqueue([=, this] (const vu8& cancelRequested) _taskQueue->Enqueue([=, this] (const vu8& cancelRequested)

View File

@@ -12,7 +12,7 @@ class FileRecyclerAdapter : public RecyclerAdapter
{ {
public: public:
u32 GetItemCount() const override; u32 GetItemCount() const override;
void BindView(View* view, int index) const override; void BindView(SharedPtr<View> view, int index) const override;
void SetIconFrameCounter(u32 iconFrameCounter) void SetIconFrameCounter(u32 iconFrameCounter)
{ {
@@ -32,6 +32,6 @@ protected:
: _fileInfoManager(fileInfoManager), _taskQueue(taskQueue) : _fileInfoManager(fileInfoManager), _taskQueue(taskQueue)
, _iconFrameCounter(0), _themeFileIconFactory(themeFileIconFactory) { } , _iconFrameCounter(0), _themeFileIconFactory(themeFileIconFactory) { }
virtual TaskResult<void> BindView(View* view, int index, virtual TaskResult<void> BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const = 0; const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const = 0;
}; };

View File

@@ -182,7 +182,7 @@ void RomBrowserController::HandleFolderLoadDoneTrigger()
LOG_DEBUG("RomBrowserStateTrigger::FolderLoadDone\n"); LOG_DEBUG("RomBrowserStateTrigger::FolderLoadDone\n");
_romBrowserViewModel.Reset(); _romBrowserViewModel.Reset();
_sdFolder = std::move(_newSdFolder); _sdFolder = std::move(_newSdFolder);
_romBrowserViewModel = SharedPtr(new RomBrowserViewModel(this, _navigateFileName)); _romBrowserViewModel = SharedPtr<RomBrowserViewModel>::MakeShared(this, _navigateFileName);
} }
void RomBrowserController::HandleLaunchTrigger() void RomBrowserController::HandleLaunchTrigger()
@@ -200,7 +200,7 @@ void RomBrowserController::HandleLaunchTrigger()
void RomBrowserController::HandleChangeDisplayModeTrigger() void RomBrowserController::HandleChangeDisplayModeTrigger()
{ {
LOG_DEBUG("RomBrowserStateTrigger::ChangeDisplayMode\n"); LOG_DEBUG("RomBrowserStateTrigger::ChangeDisplayMode\n");
_romBrowserViewModel = SharedPtr(new RomBrowserViewModel(this)); _romBrowserViewModel = SharedPtr<RomBrowserViewModel>::MakeShared(this);
} }
void RomBrowserController::UpdateLastUsedFilepath() void RomBrowserController::UpdateLastUsedFilepath()

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "core/SharedPtr.h"
#include "../views/IconGridItemView.h" #include "../views/IconGridItemView.h"
#include "../views/BannerListItemView.h" #include "../views/BannerListItemView.h"
#include "../views/AppBarView.h" #include "../views/AppBarView.h"
@@ -17,11 +18,11 @@ class IRomBrowserViewFactory
public: public:
virtual ~IRomBrowserViewFactory() = 0; virtual ~IRomBrowserViewFactory() = 0;
virtual IconGridItemView* CreateIconGridItemView() const = 0; virtual SharedPtr<IconGridItemView> CreateIconGridItemView() const = 0;
virtual IconGridItemView::VramToken UploadIconGridItemViewGraphics( virtual IconGridItemView::VramToken UploadIconGridItemViewGraphics(
const VramContext& vramContext) const { return IconGridItemView::VramToken(0); } const VramContext& vramContext) const { return IconGridItemView::VramToken(0); }
virtual BannerListItemView* CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const = 0; virtual SharedPtr<BannerListItemView> CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const = 0;
virtual BannerListItemView::VramToken UploadBannerListItemViewGraphics( virtual BannerListItemView::VramToken UploadBannerListItemViewGraphics(
const VramContext& vramContext) const { return BannerListItemView::VramToken(0); } const VramContext& vramContext) const { return BannerListItemView::VramToken(0); }
@@ -30,9 +31,9 @@ public:
virtual std::unique_ptr<BannerView> CreateFileInfoView() const = 0; virtual std::unique_ptr<BannerView> CreateFileInfoView() const = 0;
virtual std::unique_ptr<RecyclerViewBase> CreateCoverFlowRecyclerView() const = 0; virtual SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const = 0;
virtual FileRecyclerAdapter* CreateCoverFlowRecyclerAdapter( virtual SharedPtr<FileRecyclerAdapter> CreateCoverFlowRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
VBlankTextureLoader* vblankTextureLoader) const = 0; VBlankTextureLoader* vblankTextureLoader) const = 0;

View File

@@ -7,10 +7,17 @@ class MaterialColorScheme;
class CarouselRecyclerView : public CoverFlowRecyclerViewBase class CarouselRecyclerView : public CoverFlowRecyclerViewBase
{ {
struct Private { explicit Private() = default; };
public: public:
explicit CarouselRecyclerView(const MaterialColorScheme* materialColorScheme) CarouselRecyclerView(Private, const MaterialColorScheme* materialColorScheme)
: _materialColorScheme(materialColorScheme) { } : _materialColorScheme(materialColorScheme) { }
static SharedPtr<CarouselRecyclerView> CreateShared(const MaterialColorScheme* materialColorScheme)
{
return SharedPtr<CarouselRecyclerView>::MakeShared(Private(), materialColorScheme);
}
static void UploadGraphics(const VramContext& vramContext); static void UploadGraphics(const VramContext& vramContext);
void Update() override; void Update() override;

View File

@@ -9,12 +9,12 @@ MaterialAppBarView::MaterialAppBarView(int x, int y, Orientation orientation,
{ {
for (int i = 0; i < _startButtonCount + _endButtonCount; i++) for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{ {
_buttons[i] = new IconButton2DView( _buttons[i] = SharedPtr<IconButton2DView>::MakeShared(
IconButtonView::Type::Standard, IconButtonView::Type::Standard,
IconButtonView::State::NoToggle, IconButtonView::State::NoToggle,
md::sys::color::inverseOnSurface, md::sys::color::inverseOnSurface,
materialColorScheme); materialColorScheme);
AddChildTail(_buttons[i]); AddChildTail(_buttons[i].GetPointer());
} }
} }
@@ -26,7 +26,7 @@ void MaterialAppBarView::InitVram(const VramContext& vramContext)
auto iconButtonVramToken = IconButton2DView::UploadGraphics(*objVramManager); auto iconButtonVramToken = IconButton2DView::UploadGraphics(*objVramManager);
for (int i = 0; i < _startButtonCount + _endButtonCount; i++) for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{ {
static_cast<IconButton2DView*>(_buttons[i])->SetGraphics(iconButtonVramToken); static_cast<IconButton2DView*>(_buttons[i].GetPointer())->SetGraphics(iconButtonVramToken);
} }
} }
} }

View File

@@ -13,21 +13,15 @@ void MaterialCoverFlowFileRecyclerAdapter::GetViewSize(int& width, int& height)
height = COVER_HEIGHT; height = COVER_HEIGHT;
} }
View* MaterialCoverFlowFileRecyclerAdapter::CreateView() const SharedPtr<View> MaterialCoverFlowFileRecyclerAdapter::CreateView() const
{ {
return new MaterialCoverView(_vblankTextureLoader); return SharedPtr<MaterialCoverView>::MakeShared(_vblankTextureLoader);
} }
void MaterialCoverFlowFileRecyclerAdapter::DestroyView(View* view) const TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
{
auto coverView = static_cast<MaterialCoverView*>(view);
delete coverView;
}
TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(View* view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
{ {
auto coverView = static_cast<MaterialCoverView*>(view); auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
auto cover = _fileInfoManager->GetFileCover(index); auto cover = _fileInfoManager->GetFileCover(index);
if (cancelRequested) if (cancelRequested)
{ {
@@ -45,10 +39,10 @@ TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(View* view, int
return TaskResult<void>::Completed(); return TaskResult<void>::Completed();
} }
void MaterialCoverFlowFileRecyclerAdapter::ReleaseView(View* view, int index) const void MaterialCoverFlowFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
{ {
LOG_DEBUG("Releasing %d\n", index); LOG_DEBUG("Releasing %d\n", index);
auto coverView = static_cast<MaterialCoverView*>(view); auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
coverView->ClearCover(); coverView->ClearCover();
_fileInfoManager->ReleaseFileInfo(index); _fileInfoManager->ReleaseFileInfo(index);
} }

View File

@@ -19,15 +19,14 @@ public:
, _coverRepository(coverRepository) { } , _coverRepository(coverRepository) { }
void GetViewSize(int& width, int& height) const override; void GetViewSize(int& width, int& height) const override;
View* CreateView() const override; SharedPtr<View> CreateView() const override;
void DestroyView(View* view) const override; void ReleaseView(SharedPtr<View> view, int index) const override;
void ReleaseView(View* view, int index) const override;
private: private:
const IRomBrowserViewFactory* _romBrowserViewFactory; const IRomBrowserViewFactory* _romBrowserViewFactory;
VBlankTextureLoader* _vblankTextureLoader; VBlankTextureLoader* _vblankTextureLoader;
const ICoverRepository* _coverRepository; const ICoverRepository* _coverRepository;
TaskResult<void> BindView(View* view, int index, TaskResult<void> BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override; const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
}; };

View File

@@ -19,7 +19,7 @@ void MaterialCoverView::InitVram(const VramContext& vramContext)
void MaterialCoverView::Draw(GraphicsContext& graphicsContext) void MaterialCoverView::Draw(GraphicsContext& graphicsContext)
{ {
if (_cover.IsValid() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete) if (_cover.Lock() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete)
{ {
Gx::TexImageParam(_texVramOffset >> 3, false, true, false, true, GX_TEXSIZE_128, Gx::TexImageParam(_texVramOffset >> 3, false, true, false, true, GX_TEXSIZE_128,
GX_TEXSIZE_128, GX_TEXFMT_PLTT256, false, GX_TEXGEN_NONE); GX_TEXSIZE_128, GX_TEXFMT_PLTT256, false, GX_TEXGEN_NONE);
@@ -46,11 +46,11 @@ void MaterialCoverView::Draw(GraphicsContext& graphicsContext)
void MaterialCoverView::UploadCoverGraphics() void MaterialCoverView::UploadCoverGraphics()
{ {
if (_cover.IsValid()) if (auto cover = _cover.Lock())
{ {
_cover->SetTexVramOffset(_texVramOffset, _plttVramOffset); cover->SetTexVramOffset(_texVramOffset, _plttVramOffset);
_vblankTextureLoader->CancelLoad(_textureLoadRequest); _vblankTextureLoader->CancelLoad(_textureLoadRequest);
_textureLoadRequest = _cover->CreateTextureLoadRequest(); _textureLoadRequest = cover->CreateTextureLoadRequest();
_vblankTextureLoader->RequestLoad(_textureLoadRequest); _vblankTextureLoader->RequestLoad(_textureLoadRequest);
} }
} }

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <memory> #include "core/AtomicSharedPtr.h"
#include "core/SharedPtr.h"
#include "gui/views/View.h" #include "gui/views/View.h"
#include "romBrowser/FileType/FileCover.h" #include "romBrowser/FileType/FileCover.h"
#include "gui/VBlankTextureLoader.h" #include "gui/VBlankTextureLoader.h"
@@ -26,20 +25,14 @@ public:
} }
void SetCover(SharedPtr<FileCover> cover) void SetCover(SharedPtr<FileCover> cover)
{
if (_cover.IsValid())
{ {
_vblankTextureLoader->CancelLoad(_textureLoadRequest); _vblankTextureLoader->CancelLoad(_textureLoadRequest);
}
_cover = std::move(cover); _cover = std::move(cover);
} }
void ClearCover() void ClearCover()
{
if (_cover.IsValid())
{ {
_vblankTextureLoader->CancelLoad(_textureLoadRequest); _vblankTextureLoader->CancelLoad(_textureLoadRequest);
}
_cover.Reset(); _cover.Reset();
} }
@@ -47,7 +40,7 @@ public:
private: private:
VBlankTextureLoader* _vblankTextureLoader; VBlankTextureLoader* _vblankTextureLoader;
SharedPtr<FileCover> _cover; AtomicSharedPtr<FileCover> _cover;
VBlankTextureLoadRequest _textureLoadRequest; VBlankTextureLoadRequest _textureLoadRequest;
u32 _texVramOffset = 0; u32 _texVramOffset = 0;
u32 _plttVramOffset = 0; u32 _plttVramOffset = 0;

View File

@@ -18,9 +18,9 @@ public:
const IFontRepository* fontRepository) const IFontRepository* fontRepository)
: _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { } : _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
IconGridItemView* CreateIconGridItemView() const override SharedPtr<IconGridItemView> CreateIconGridItemView() const override
{ {
return new MaterialIconGridItemView(_materialColorScheme); return SharedPtr<MaterialIconGridItemView>::MakeShared(_materialColorScheme);
} }
IconGridItemView::VramToken UploadIconGridItemViewGraphics( IconGridItemView::VramToken UploadIconGridItemViewGraphics(
@@ -29,9 +29,9 @@ public:
return MaterialIconGridItemView::UploadGraphics(vramContext); return MaterialIconGridItemView::UploadGraphics(vramContext);
} }
BannerListItemView* CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override SharedPtr<BannerListItemView> CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new MaterialBannerListItemView(_materialColorScheme, _fontRepository); return SharedPtr<MaterialBannerListItemView>::MakeShared(_materialColorScheme, _fontRepository);
} }
BannerListItemView::VramToken UploadBannerListItemViewGraphics( BannerListItemView::VramToken UploadBannerListItemViewGraphics(
@@ -51,16 +51,16 @@ public:
return std::make_unique<MaterialFileInfoCardView>(_materialColorScheme, _fontRepository); return std::make_unique<MaterialFileInfoCardView>(_materialColorScheme, _fontRepository);
} }
std::unique_ptr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
{ {
return std::make_unique<CarouselRecyclerView>(_materialColorScheme); return CarouselRecyclerView::CreateShared(_materialColorScheme);
} }
FileRecyclerAdapter* CreateCoverFlowRecyclerAdapter( SharedPtr<FileRecyclerAdapter> CreateCoverFlowRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
VBlankTextureLoader* vblankTextureLoader) const override VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new MaterialCoverFlowFileRecyclerAdapter( return SharedPtr<MaterialCoverFlowFileRecyclerAdapter>::MakeShared(
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), &viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository()); themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
} }

View File

@@ -4,8 +4,6 @@
#include "romBrowser/views/IconButton3DView.h" #include "romBrowser/views/IconButton3DView.h"
#include "CustomAppBarView.h" #include "CustomAppBarView.h"
#define BLOCK_VTX_PACK(x, y, z) (((x)&0x3FF) | ((((y) >> 3) & 0x3FF) << 10) | ((z) << 20))
CustomAppBarView::CustomAppBarView(int x, int y, Orientation orientation, CustomAppBarView::CustomAppBarView(int x, int y, Orientation orientation,
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme, int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme,
u32 scrimTexVramOffset, u32 scrimPlttVramOffset) u32 scrimTexVramOffset, u32 scrimPlttVramOffset)
@@ -14,12 +12,12 @@ CustomAppBarView::CustomAppBarView(int x, int y, Orientation orientation,
{ {
for (int i = 0; i < _startButtonCount + _endButtonCount; i++) for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{ {
_buttons[i] = new IconButton3DView( _buttons[i] = SharedPtr<IconButton3DView>::MakeShared(
IconButtonView::Type::Tonal, IconButtonView::Type::Tonal,
IconButtonView::State::NoToggle, IconButtonView::State::NoToggle,
md::sys::color::inverseOnSurface, md::sys::color::inverseOnSurface,
materialColorScheme); materialColorScheme);
AddChildTail(_buttons[i]); AddChildTail(_buttons[i].GetPointer());
} }
} }

View File

@@ -21,15 +21,15 @@ public:
const IFontRepository* fontRepository) const IFontRepository* fontRepository)
: _customThemeInfo(customThemeInfo), _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { } : _customThemeInfo(customThemeInfo), _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
IconGridItemView* CreateIconGridItemView() const override SharedPtr<IconGridItemView> CreateIconGridItemView() const override
{ {
return new CustomIconGridItemView(_customThemeInfo, _gridCellTexVramOffset, _gridCellPlttVramOffset, return SharedPtr<CustomIconGridItemView>::MakeShared(_customThemeInfo, _gridCellTexVramOffset, _gridCellPlttVramOffset,
_gridCellSelectedTexVramOffset, _gridCellSelectedPlttVramOffset); _gridCellSelectedTexVramOffset, _gridCellSelectedPlttVramOffset);
} }
BannerListItemView* CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override SharedPtr<BannerListItemView> CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new CustomBannerListItemView(_customThemeInfo, _materialColorScheme, _fontRepository, return SharedPtr<CustomBannerListItemView>::MakeShared(_customThemeInfo, _materialColorScheme, _fontRepository,
_bannerListCellTexVramOffset, _bannerListCellPlttVramOffset, _bannerListCellTexVramOffset, _bannerListCellPlttVramOffset,
_bannerListCellSelectedTexVramOffset, _bannerListCellSelectedPlttVramOffset, vblankTextureLoader); _bannerListCellSelectedTexVramOffset, _bannerListCellSelectedPlttVramOffset, vblankTextureLoader);
} }
@@ -51,16 +51,16 @@ public:
return std::make_unique<CustomFileInfoView>(_customThemeInfo, _fontRepository); return std::make_unique<CustomFileInfoView>(_customThemeInfo, _fontRepository);
} }
std::unique_ptr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
{ {
return std::make_unique<CoverFlowRecyclerView>(); return CoverFlowRecyclerView::CreateShared();
} }
FileRecyclerAdapter* CreateCoverFlowRecyclerAdapter( SharedPtr<FileRecyclerAdapter> CreateCoverFlowRecyclerAdapter(
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
VBlankTextureLoader* vblankTextureLoader) const override VBlankTextureLoader* vblankTextureLoader) const override
{ {
return new CoverFlowFileRecyclerAdapter( return SharedPtr<CoverFlowFileRecyclerAdapter>::MakeShared(
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), &viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository()); themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
} }

View File

@@ -6,21 +6,12 @@
AppBarView::AppBarView(int x, int y, Orientation orientation, AppBarView::AppBarView(int x, int y, Orientation orientation,
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme) int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme)
: _orientation(orientation) : _orientation(orientation)
, _buttons(std::make_unique<IconButtonView*[]>(startButtonCount + endButtonCount)) , _buttons(std::make_unique<SharedPtr<IconButtonView>[]>(startButtonCount + endButtonCount))
, _startButtonCount(startButtonCount), _endButtonCount(endButtonCount) , _startButtonCount(startButtonCount), _endButtonCount(endButtonCount)
{ {
SetPosition(x, y); SetPosition(x, y);
} }
AppBarView::~AppBarView()
{
for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{
delete _buttons[i];
_buttons[i] = nullptr;
}
}
Rectangle AppBarView::GetBounds() const Rectangle AppBarView::GetBounds() const
{ {
if (_orientation == Orientation::Horizontal) if (_orientation == Orientation::Horizontal)
@@ -39,9 +30,9 @@ void AppBarView::Update()
ViewContainer::Update(); ViewContainer::Update();
} }
View* AppBarView::MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> AppBarView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
int idx = FindButtonIndex(currentFocus); int idx = FindButtonIndex(currentFocus.GetPointer());
if (idx >= 0) if (idx >= 0)
{ {
if (_orientation == Orientation::Horizontal) if (_orientation == Orientation::Horizontal)
@@ -71,21 +62,28 @@ View* AppBarView::MoveFocus(View* currentFocus, FocusMoveDirection direction, Vi
else if ((_orientation == Orientation::Horizontal && (direction == FocusMoveDirection::Up || direction == FocusMoveDirection::Down)) || else if ((_orientation == Orientation::Horizontal && (direction == FocusMoveDirection::Up || direction == FocusMoveDirection::Down)) ||
(_orientation == Orientation::Vertical && (direction == FocusMoveDirection::Left || direction == FocusMoveDirection::Right))) (_orientation == Orientation::Vertical && (direction == FocusMoveDirection::Left || direction == FocusMoveDirection::Right)))
{ {
if (currentFocus == nullptr) if (!currentFocus)
return _buttons[0]; return _buttons[0];
Point curFocusPoint = currentFocus->GetBounds().GetCenter(); Point curFocusPoint = currentFocus->GetBounds().GetCenter();
s64 bestDistance = std::numeric_limits<s64>::max(); s64 bestDistance = std::numeric_limits<s64>::max();
View* nearestButton = nullptr; int nearestButton = -1;
for (int i = 0; i < _startButtonCount + _endButtonCount; i++) for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{ {
s64 distance = curFocusPoint.DistanceSquaredTo(_buttons[i]->GetBounds().GetCenter()); s64 distance = curFocusPoint.DistanceSquaredTo(_buttons[i]->GetBounds().GetCenter());
if (distance < bestDistance) if (distance < bestDistance)
{ {
bestDistance = distance; bestDistance = distance;
nearestButton = _buttons[i]; nearestButton = i;
} }
} }
return nearestButton; if (nearestButton >= 0)
{
return _buttons[nearestButton];
}
else
{
return nullptr;
}
} }
else else
return View::MoveFocus(currentFocus, direction, this); return View::MoveFocus(currentFocus, direction, this);
@@ -126,7 +124,7 @@ int AppBarView::FindButtonIndex(const View* view)
{ {
for (int i = 0; i < _startButtonCount + _endButtonCount; i++) for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{ {
if (_buttons[i] == view) if (_buttons[i].GetPointer() == view)
{ {
return i; return i;
} }

View File

@@ -14,8 +14,6 @@ public:
Vertical Vertical
}; };
virtual ~AppBarView();
void SetButtonIcon(int button, u32 vramOffset) void SetButtonIcon(int button, u32 vramOffset)
{ {
_buttons[button]->SetIconVramOffset(vramOffset); _buttons[button]->SetIconVramOffset(vramOffset);
@@ -28,14 +26,14 @@ public:
Rectangle GetBounds() const override; Rectangle GetBounds() const override;
void Update() override; void Update() override;
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override; SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
void Focus(FocusManager& focusManager, int button); void Focus(FocusManager& focusManager, int button);
constexpr Orientation GetOrientation() const { return _orientation; } constexpr Orientation GetOrientation() const { return _orientation; }
protected: protected:
Orientation _orientation; Orientation _orientation;
std::unique_ptr<IconButtonView*[]> _buttons; std::unique_ptr<SharedPtr<IconButtonView>[]> _buttons;
int _startButtonCount; int _startButtonCount;
int _endButtonCount; int _endButtonCount;

View File

@@ -5,7 +5,16 @@
class CoverFlowRecyclerView : public CoverFlowRecyclerViewBase class CoverFlowRecyclerView : public CoverFlowRecyclerViewBase
{ {
struct Private { explicit Private() = default; };
public: public:
explicit CoverFlowRecyclerView(Private) { }
static SharedPtr<CoverFlowRecyclerView> CreateShared()
{
return SharedPtr<CoverFlowRecyclerView>::MakeShared(Private());
}
void Update() override; void Update() override;
void Draw(GraphicsContext& graphicsContext) override; void Draw(GraphicsContext& graphicsContext) override;

View File

@@ -1,6 +1,14 @@
#include "common.h" #include "common.h"
#include "CoverFlowRecyclerViewBase.h" #include "CoverFlowRecyclerViewBase.h"
CoverFlowRecyclerViewBase::~CoverFlowRecyclerViewBase()
{
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
_adapter->ReleaseView(_viewPool[i].view, _viewPool[i].itemIdx);
}
}
void CoverFlowRecyclerViewBase::InitVram(const VramContext& vramContext) void CoverFlowRecyclerViewBase::InitVram(const VramContext& vramContext)
{ {
for (u32 i = 0; i < _viewPool.size(); i++) for (u32 i = 0; i < _viewPool.size(); i++)
@@ -9,17 +17,18 @@ void CoverFlowRecyclerViewBase::InitVram(const VramContext& vramContext)
} }
} }
void CoverFlowRecyclerViewBase::SetAdapter(const RecyclerAdapter* adapter, int initialSelectedIndex) void CoverFlowRecyclerViewBase::SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex)
{ {
if (_adapter) if (_adapter)
{ {
_selectedItem = nullptr; _selectedItem = nullptr;
for (u32 i = 0; i < _viewPool.size(); i++) for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{ {
_adapter->DestroyView(_viewPool[i].view); _adapter->ReleaseView(_viewPool[i].view, _viewPool[i].itemIdx);
_viewPool[i].view.Reset();
} }
} }
_adapter = adapter; _adapter = std::move(adapter);
// _adapter->GetViewSize(_itemWidth, _itemHeight); // _adapter->GetViewSize(_itemWidth, _itemHeight);
_itemCount = _adapter->GetItemCount(); _itemCount = _adapter->GetItemCount();
@@ -41,14 +50,14 @@ void CoverFlowRecyclerViewBase::SetAdapter(const RecyclerAdapter* adapter, int i
} }
} }
View* CoverFlowRecyclerViewBase::MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> CoverFlowRecyclerViewBase::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (!_selectedItem || currentFocus != _selectedItem->view) if (!_selectedItem || currentFocus.GetPointer() != _selectedItem->view.GetPointer())
{ {
// incoming focus // incoming focus
if (direction == FocusMoveDirection::Down) if (direction == FocusMoveDirection::Down)
{ {
return _selectedItem ? _selectedItem->view : this; return _selectedItem ? _selectedItem->view : SharedFromThis();
} }
else else
{ {
@@ -78,7 +87,7 @@ View* CoverFlowRecyclerViewBase::MoveFocus(View* currentFocus, FocusMoveDirectio
return View::MoveFocus(currentFocus, direction, this); return View::MoveFocus(currentFocus, direction, this);
} }
return _selectedItem ? _selectedItem->view : this; return _selectedItem ? _selectedItem->view : SharedFromThis();
} }
CoverFlowRecyclerViewBase::ViewPoolEntry* CoverFlowRecyclerViewBase::GetViewPoolEntryByItemIndex(int itemIdx) CoverFlowRecyclerViewBase::ViewPoolEntry* CoverFlowRecyclerViewBase::GetViewPoolEntryByItemIndex(int itemIdx)

View File

@@ -1,13 +1,16 @@
#pragma once #pragma once
#include <array> #include <array>
#include "core/EnableSharedFromThis.h"
#include "gui/views/RecyclerViewBase.h" #include "gui/views/RecyclerViewBase.h"
class CoverFlowRecyclerViewBase : public RecyclerViewBase class CoverFlowRecyclerViewBase : public RecyclerViewBase, public EnableSharedFromThis<CoverFlowRecyclerViewBase>
{ {
public: public:
~CoverFlowRecyclerViewBase() override;
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
void SetAdapter(const RecyclerAdapter* adapter, int initialSelectedIndex = 0) override; void SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex = 0) override;
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override; SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
Rectangle GetBounds() const override Rectangle GetBounds() const override
{ {
@@ -16,7 +19,14 @@ public:
void Focus(FocusManager& focusManager) override void Focus(FocusManager& focusManager) override
{ {
focusManager.Focus(_selectedItem ? _selectedItem->view : this); if (_selectedItem == nullptr)
{
focusManager.Focus(SharedFromThis());
}
else
{
focusManager.Focus(_selectedItem->view);
}
} }
int GetSelectedItem() const override int GetSelectedItem() const override
@@ -27,7 +37,7 @@ public:
protected: protected:
struct ViewPoolEntry struct ViewPoolEntry
{ {
View* view; SharedPtr<View> view;
int itemIdx = -1; int itemIdx = -1;
}; };

View File

@@ -19,7 +19,7 @@ void CoverView::InitVram(const VramContext& vramContext)
void CoverView::Draw(GraphicsContext& graphicsContext) void CoverView::Draw(GraphicsContext& graphicsContext)
{ {
if (_cover.IsValid() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete) if (_cover.Lock() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete)
{ {
Gx::TexImageParam(_texVramOffset >> 3, false, true, false, true, GX_TEXSIZE_128, Gx::TexImageParam(_texVramOffset >> 3, false, true, false, true, GX_TEXSIZE_128,
GX_TEXSIZE_128, GX_TEXFMT_PLTT256, false, GX_TEXGEN_NONE); GX_TEXSIZE_128, GX_TEXFMT_PLTT256, false, GX_TEXGEN_NONE);
@@ -85,11 +85,11 @@ void CoverView::Draw(GraphicsContext& graphicsContext)
void CoverView::UploadCoverGraphics() void CoverView::UploadCoverGraphics()
{ {
if (_cover.IsValid()) if (auto cover = _cover.Lock())
{ {
_cover->SetTexVramOffset(_texVramOffset, _plttVramOffset); cover->SetTexVramOffset(_texVramOffset, _plttVramOffset);
_vblankTextureLoader->CancelLoad(_textureLoadRequest); _vblankTextureLoader->CancelLoad(_textureLoadRequest);
_textureLoadRequest = _cover->CreateTextureLoadRequest(); _textureLoadRequest = cover->CreateTextureLoadRequest();
_vblankTextureLoader->RequestLoad(_textureLoadRequest); _vblankTextureLoader->RequestLoad(_textureLoadRequest);
} }
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "core/SharedPtr.h" #include "core/AtomicSharedPtr.h"
#include "gui/views/View.h" #include "gui/views/View.h"
#include "../FileType/FileCover.h" #include "../FileType/FileCover.h"
#include "gui/VBlankTextureLoader.h" #include "gui/VBlankTextureLoader.h"
@@ -28,20 +28,14 @@ public:
} }
void SetCover(SharedPtr<FileCover> cover) void SetCover(SharedPtr<FileCover> cover)
{
if (_cover.IsValid())
{ {
_vblankTextureLoader->CancelLoad(_textureLoadRequest); _vblankTextureLoader->CancelLoad(_textureLoadRequest);
}
_cover = std::move(cover); _cover = std::move(cover);
} }
void ClearCover() void ClearCover()
{
if (_cover.IsValid())
{ {
_vblankTextureLoader->CancelLoad(_textureLoadRequest); _vblankTextureLoader->CancelLoad(_textureLoadRequest);
}
_cover.Reset(); _cover.Reset();
} }
@@ -49,7 +43,7 @@ public:
private: private:
VBlankTextureLoader* _vblankTextureLoader; VBlankTextureLoader* _vblankTextureLoader;
SharedPtr<FileCover> _cover; AtomicSharedPtr<FileCover> _cover;
VBlankTextureLoadRequest _textureLoadRequest; VBlankTextureLoadRequest _textureLoadRequest;
u32 _texVramOffset = 0; u32 _texVramOffset = 0;
u32 _plttVramOffset = 0; u32 _plttVramOffset = 0;

View File

@@ -70,13 +70,13 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView(
for (auto& layoutOption : _layoutOptions) for (auto& layoutOption : _layoutOptions)
{ {
layoutOption = CreateLayoutOptionIconButton(); layoutOption = CreateLayoutOptionIconButton();
AddChildTail(&layoutOption); AddChildTail(layoutOption.GetPointer());
} }
for (auto& sortOption : _sortOptions) for (auto& sortOption : _sortOptions)
{ {
sortOption = CreateSortOptionIconButton(); sortOption = CreateSortOptionIconButton();
AddChildTail(&sortOption); AddChildTail(sortOption.GetPointer());
} }
// for (auto& filterOption : _filterOptions) // for (auto& filterOption : _filterOptions)
@@ -88,38 +88,48 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView(
// _filterOptions[0].SetState(IconButtonView::State::ToggleSelected); // _filterOptions[0].SetState(IconButtonView::State::ToggleSelected);
} }
IconButton2DView DisplaySettingsBottomSheetView::CreateLayoutOptionIconButton() SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateLayoutOptionIconButton()
{
IconButton2DView layoutOption
{ {
auto layoutOption = SharedPtr<IconButton2DView>::MakeShared(
IconButtonView::Type::Tonal, IconButtonView::Type::Tonal,
IconButtonView::State::ToggleUnselected, IconButtonView::State::ToggleUnselected,
md::sys::color::surfaceContainerLow, md::sys::color::surfaceContainerLow,
_materialColorScheme _materialColorScheme
}; );
layoutOption.SetAction([] (IconButtonView* sender, void* arg) layoutOption->SetAction([] (IconButtonView* sender, void* arg)
{ {
auto self = reinterpret_cast<DisplaySettingsBottomSheetView*>(arg); auto self = reinterpret_cast<DisplaySettingsBottomSheetView*>(arg);
u32 idx = ((IconButton2DView*)sender) - &self->_layoutOptions[0]; for (u32 i = 0; i < self->_layoutOptions.size(); i++)
self->_viewModel->SetRomBrowserDisplayMode(sRomBrowserDisplayModes[idx]); {
if (self->_layoutOptions[i].GetPointer() == sender)
{
self->_viewModel->SetRomBrowserDisplayMode(sRomBrowserDisplayModes[i]);
break;
}
}
}, this); }, this);
return layoutOption; return layoutOption;
} }
IconButton2DView DisplaySettingsBottomSheetView::CreateSortOptionIconButton() SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateSortOptionIconButton()
{
IconButton2DView sortOption
{ {
auto sortOption = SharedPtr<IconButton2DView>::MakeShared(
IconButtonView::Type::Tonal, IconButtonView::Type::Tonal,
IconButtonView::State::ToggleUnselected, IconButtonView::State::ToggleUnselected,
md::sys::color::surfaceContainerLow, md::sys::color::surfaceContainerLow,
_materialColorScheme _materialColorScheme
}; );
sortOption.SetAction([] (IconButtonView* sender, void* arg) sortOption->SetAction([] (IconButtonView* sender, void* arg)
{ {
auto self = reinterpret_cast<DisplaySettingsBottomSheetView*>(arg); auto self = reinterpret_cast<DisplaySettingsBottomSheetView*>(arg);
u32 idx = ((IconButton2DView*)sender) - &self->_sortOptions[0]; for (u32 i = 0; i < self->_sortOptions.size(); i++)
self->_viewModel->SetRomBrowserSortMode(sRomBrowserSortModes[idx]); {
if (self->_sortOptions[i].GetPointer() == sender)
{
self->_viewModel->SetRomBrowserSortMode(sRomBrowserSortModes[i]);
break;
}
}
}, this); }, this);
return sortOption; return sortOption;
} }
@@ -144,14 +154,14 @@ void DisplaySettingsBottomSheetView::InitVram(const VramContext& vramContext)
if (objVramManager) if (objVramManager)
{ {
// layout options // layout options
_layoutOptions[0].SetIconVramOffset(LoadIcon(*objVramManager, hGridIconTiles, hGridIconTilesLen)); _layoutOptions[0]->SetIconVramOffset(LoadIcon(*objVramManager, hGridIconTiles, hGridIconTilesLen));
_layoutOptions[1].SetIconVramOffset(LoadIcon(*objVramManager, vGridIconTiles, vGridIconTilesLen)); _layoutOptions[1]->SetIconVramOffset(LoadIcon(*objVramManager, vGridIconTiles, vGridIconTilesLen));
_layoutOptions[2].SetIconVramOffset(LoadIcon(*objVramManager, bannerListIconTiles, bannerListIconTilesLen)); _layoutOptions[2]->SetIconVramOffset(LoadIcon(*objVramManager, bannerListIconTiles, bannerListIconTilesLen));
_layoutOptions[3].SetIconVramOffset(LoadIcon(*objVramManager, coverflowIconTiles, coverflowIconTilesLen)); _layoutOptions[3]->SetIconVramOffset(LoadIcon(*objVramManager, coverflowIconTiles, coverflowIconTilesLen));
// sort options // sort options
_sortOptions[0].SetIconVramOffset(LoadIcon(*objVramManager, sortNameAscendingIconTiles, sortNameAscendingIconTilesLen)); _sortOptions[0]->SetIconVramOffset(LoadIcon(*objVramManager, sortNameAscendingIconTiles, sortNameAscendingIconTilesLen));
_sortOptions[1].SetIconVramOffset(LoadIcon(*objVramManager, sortNameDescendingIconTiles, sortNameDescendingIconTilesLen)); _sortOptions[1]->SetIconVramOffset(LoadIcon(*objVramManager, sortNameDescendingIconTiles, sortNameDescendingIconTilesLen));
// _sortOptions[2].SetIconVramOffset(LoadIcon(objVramManager, recentIconTiles, recentIconTilesLen)); // _sortOptions[2].SetIconVramOffset(LoadIcon(objVramManager, recentIconTiles, recentIconTilesLen));
// filter options // filter options
@@ -180,8 +190,8 @@ void DisplaySettingsBottomSheetView::Update()
u32 idx = 0; u32 idx = 0;
for (auto& layoutOption : _layoutOptions) for (auto& layoutOption : _layoutOptions)
{ {
layoutOption.SetPosition(x, _position.y + 38); layoutOption->SetPosition(x, _position.y + 38);
layoutOption.SetState(sRomBrowserDisplayModes[idx] == selectedDisplayMode layoutOption->SetState(sRomBrowserDisplayModes[idx] == selectedDisplayMode
? IconButtonView::State::ToggleSelected ? IconButtonView::State::ToggleSelected
: IconButtonView::State::ToggleUnselected); : IconButtonView::State::ToggleUnselected);
x += 32; x += 32;
@@ -192,8 +202,8 @@ void DisplaySettingsBottomSheetView::Update()
idx = 0; idx = 0;
for (auto& sortOption : _sortOptions) for (auto& sortOption : _sortOptions)
{ {
sortOption.SetPosition(x, _position.y + 70); sortOption->SetPosition(x, _position.y + 70);
sortOption.SetState(sRomBrowserSortModes[idx] == selectedSortMode sortOption->SetState(sRomBrowserSortModes[idx] == selectedSortMode
? IconButtonView::State::ToggleSelected ? IconButtonView::State::ToggleSelected
: IconButtonView::State::ToggleUnselected); : IconButtonView::State::ToggleUnselected);
x += 32; x += 32;
@@ -237,25 +247,25 @@ bool DisplaySettingsBottomSheetView::HandleInput(
return false; return false;
} }
View* DisplaySettingsBottomSheetView::MoveFocus(View* currentFocus, SharedPtr<View> DisplaySettingsBottomSheetView::MoveFocus(const SharedPtr<View>& currentFocus,
FocusMoveDirection direction, View* source) FocusMoveDirection direction, View* source)
{ {
int idx = 0; int idx = 0;
for (auto& layoutOption : _layoutOptions) for (auto& layoutOption : _layoutOptions)
{ {
if (currentFocus == &layoutOption) if (currentFocus.GetPointer() == layoutOption.GetPointer())
{ {
if (direction == FocusMoveDirection::Left) if (direction == FocusMoveDirection::Left)
{ {
if (--idx < 0) if (--idx < 0)
idx += _layoutOptions.size(); idx += _layoutOptions.size();
return &_layoutOptions[idx]; return _layoutOptions[idx];
} }
else if (direction == FocusMoveDirection::Right) else if (direction == FocusMoveDirection::Right)
{ {
if (++idx >= (int)_layoutOptions.size()) if (++idx >= (int)_layoutOptions.size())
idx = 0; idx = 0;
return &_layoutOptions[idx]; return _layoutOptions[idx];
} }
// else if (direction == FocusMoveDirection::Up) // else if (direction == FocusMoveDirection::Up)
// { // {
@@ -267,7 +277,7 @@ View* DisplaySettingsBottomSheetView::MoveFocus(View* currentFocus,
{ {
if (idx >= (int)_sortOptions.size()) if (idx >= (int)_sortOptions.size())
idx = _sortOptions.size() - 1; idx = _sortOptions.size() - 1;
return &_sortOptions[idx]; return _sortOptions[idx];
} }
} }
idx++; idx++;
@@ -275,25 +285,25 @@ View* DisplaySettingsBottomSheetView::MoveFocus(View* currentFocus,
idx = 0; idx = 0;
for (auto& sortOption : _sortOptions) for (auto& sortOption : _sortOptions)
{ {
if (currentFocus == &sortOption) if (currentFocus.GetPointer() == sortOption.GetPointer())
{ {
if (direction == FocusMoveDirection::Left) if (direction == FocusMoveDirection::Left)
{ {
if (--idx < 0) if (--idx < 0)
idx += _sortOptions.size(); idx += _sortOptions.size();
return &_sortOptions[idx]; return _sortOptions[idx];
} }
else if (direction == FocusMoveDirection::Right) else if (direction == FocusMoveDirection::Right)
{ {
if (++idx >= (int)_sortOptions.size()) if (++idx >= (int)_sortOptions.size())
idx = 0; idx = 0;
return &_sortOptions[idx]; return _sortOptions[idx];
} }
else //if (direction == FocusMoveDirection::Up) else //if (direction == FocusMoveDirection::Up)
{ {
if (idx >= (int)_layoutOptions.size()) if (idx >= (int)_layoutOptions.size())
idx = _layoutOptions.size() - 1; idx = _layoutOptions.size() - 1;
return &_layoutOptions[idx]; return _layoutOptions[idx];
} }
// else //if (direction == FocusMoveDirection::Down) // else //if (direction == FocusMoveDirection::Down)
// { // {
@@ -343,9 +353,13 @@ void DisplaySettingsBottomSheetView::SetGraphics(
const IconButton2DView::VramToken& iconButtonVramToken) const IconButton2DView::VramToken& iconButtonVramToken)
{ {
for (auto& layoutOption : _layoutOptions) for (auto& layoutOption : _layoutOptions)
layoutOption.SetGraphics(iconButtonVramToken); {
layoutOption->SetGraphics(iconButtonVramToken);
}
for (auto& sortOption : _sortOptions) for (auto& sortOption : _sortOptions)
sortOption.SetGraphics(iconButtonVramToken); {
sortOption->SetGraphics(iconButtonVramToken);
}
// for (auto& filterOption : _filterOptions) // for (auto& filterOption : _filterOptions)
// filterOption.SetGraphics(iconButtonVramToken); // filterOption.SetGraphics(iconButtonVramToken);
} }

View File

@@ -19,14 +19,14 @@ public:
void Update() override; void Update() override;
void Draw(GraphicsContext& graphicsContext) override; void Draw(GraphicsContext& graphicsContext) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override; bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
View* MoveFocus(View* currentFocus, SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus,
FocusMoveDirection direction, View* source) override; FocusMoveDirection direction, View* source) override;
void SetGraphics(const IconButton2DView::VramToken& iconButtonVramToken); void SetGraphics(const IconButton2DView::VramToken& iconButtonVramToken);
void Focus(FocusManager& focusManager) override void Focus(FocusManager& focusManager) override
{ {
focusManager.Focus(&_layoutOptions[0]); focusManager.Focus(_layoutOptions[0]);
} }
private: private:
@@ -37,14 +37,14 @@ private:
Label2DView _sortingLabel; Label2DView _sortingLabel;
// LabelView _filtersLabel; // LabelView _filtersLabel;
std::array<IconButton2DView, 4> _layoutOptions; std::array<SharedPtr<IconButton2DView>, 4> _layoutOptions;
std::array<IconButton2DView, /*3*/2> _sortOptions; std::array<SharedPtr<IconButton2DView>, /*3*/2> _sortOptions;
// std::array<IconButton2DView, 5> _filterOptions; // std::array<IconButton2DView, 5> _filterOptions;
const MaterialColorScheme* _materialColorScheme; const MaterialColorScheme* _materialColorScheme;
IconButton2DView CreateLayoutOptionIconButton(); SharedPtr<IconButton2DView> CreateLayoutOptionIconButton();
IconButton2DView CreateSortOptionIconButton(); SharedPtr<IconButton2DView> CreateSortOptionIconButton();
// IconButton2DView CreateFilterOptionIconButton(); // IconButton2DView CreateFilterOptionIconButton();
void UpdateLabels(); void UpdateLabels();

View File

@@ -13,15 +13,15 @@ NdsGameDetailsBottomSheetView::NdsGameDetailsBottomSheetView(
IRomBrowserController* romBrowserController, const MaterialColorScheme* materialColorScheme, IRomBrowserController* romBrowserController, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository) const IFontRepository* fontRepository)
: _romBrowserController(romBrowserController) : _romBrowserController(romBrowserController)
, _cheatsChip(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository) , _cheatsChip(SharedPtr<ChipView>::MakeShared(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository))
, _favoriteChip(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository) , _favoriteChip(SharedPtr<ChipView>::MakeShared(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository))
{ {
_cheatsChip.SetText(u"Cheats"); _cheatsChip->SetText(u"Cheats");
_cheatsChip.SetSelected(false); _cheatsChip->SetSelected(false);
AddChildTail(&_cheatsChip); AddChildTail(_cheatsChip.GetPointer());
_favoriteChip.SetText(u"Favorite"); _favoriteChip->SetText(u"Favorite");
_favoriteChip.SetSelected(true); _favoriteChip->SetSelected(true);
AddChildTail(&_favoriteChip); AddChildTail(_favoriteChip.GetPointer());
} }
void NdsGameDetailsBottomSheetView::InitVram(const VramContext& vramContext) void NdsGameDetailsBottomSheetView::InitVram(const VramContext& vramContext)
@@ -37,15 +37,15 @@ void NdsGameDetailsBottomSheetView::InitVram(const VramContext& vramContext)
_smallHeartIconFilledVramOffset = objVramManager->Alloc(smallHeartIconFilledTilesLen); _smallHeartIconFilledVramOffset = objVramManager->Alloc(smallHeartIconFilledTilesLen);
dma_ntrCopy32(3, smallHeartIconFilledTiles, objVramManager->GetVramAddress(_smallHeartIconFilledVramOffset), smallHeartIconFilledTilesLen); dma_ntrCopy32(3, smallHeartIconFilledTiles, objVramManager->GetVramAddress(_smallHeartIconFilledVramOffset), smallHeartIconFilledTilesLen);
_favoriteChip.SetIcon(true, _smallHeartIconFilledVramOffset); _favoriteChip->SetIcon(true, _smallHeartIconFilledVramOffset);
} }
} }
void NdsGameDetailsBottomSheetView::Update() void NdsGameDetailsBottomSheetView::Update()
{ {
BottomSheetView::Update(); BottomSheetView::Update();
_cheatsChip.SetPosition(92, _position.y + 21); _cheatsChip->SetPosition(92, _position.y + 21);
_favoriteChip.SetPosition(162, _position.y + 21); _favoriteChip->SetPosition(162, _position.y + 21);
} }
void NdsGameDetailsBottomSheetView::Draw(GraphicsContext& graphicsContext) void NdsGameDetailsBottomSheetView::Draw(GraphicsContext& graphicsContext)
@@ -59,13 +59,13 @@ void NdsGameDetailsBottomSheetView::Draw(GraphicsContext& graphicsContext)
graphicsContext.ResetClipArea(); graphicsContext.ResetClipArea();
} }
View* NdsGameDetailsBottomSheetView::MoveFocus(View* currentFocus, SharedPtr<View> NdsGameDetailsBottomSheetView::MoveFocus(const SharedPtr<View>& currentFocus,
FocusMoveDirection direction, View* source) FocusMoveDirection direction, View* source)
{ {
if (currentFocus == &_cheatsChip && direction == FocusMoveDirection::Right) if (currentFocus.GetPointer() == _cheatsChip.GetPointer() && direction == FocusMoveDirection::Right)
return &_favoriteChip; return _favoriteChip;
else if (currentFocus == &_favoriteChip && direction == FocusMoveDirection::Left) else if (currentFocus.GetPointer() == _favoriteChip.GetPointer() && direction == FocusMoveDirection::Left)
return &_cheatsChip; return _cheatsChip;
return nullptr; return nullptr;
} }

View File

@@ -16,8 +16,8 @@ public:
void SetGraphics(const ChipView::VramToken& chipVramToken) void SetGraphics(const ChipView::VramToken& chipVramToken)
{ {
_cheatsChip.SetGraphics(chipVramToken); _cheatsChip->SetGraphics(chipVramToken);
_favoriteChip.SetGraphics(chipVramToken); _favoriteChip->SetGraphics(chipVramToken);
} }
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
@@ -27,10 +27,10 @@ public:
void Focus(FocusManager& focusManager) override void Focus(FocusManager& focusManager) override
{ {
focusManager.Focus(&_cheatsChip); focusManager.Focus(_cheatsChip);
} }
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override; SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override; bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
@@ -38,6 +38,6 @@ private:
IRomBrowserController* _romBrowserController; IRomBrowserController* _romBrowserController;
u32 _smallHeartIconVramOffset; u32 _smallHeartIconVramOffset;
u32 _smallHeartIconFilledVramOffset; u32 _smallHeartIconFilledVramOffset;
ChipView _cheatsChip; SharedPtr<ChipView> _cheatsChip;
ChipView _favoriteChip; SharedPtr<ChipView> _favoriteChip;
}; };

View File

@@ -114,9 +114,9 @@ void RomBrowserAppBarView::VBlank()
_appBarView->VBlank(); _appBarView->VBlank();
} }
View* RomBrowserAppBarView::MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> RomBrowserAppBarView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (currentFocus == nullptr) if (!currentFocus)
{ {
return nullptr; return nullptr;
} }

View File

@@ -23,7 +23,7 @@ public:
return Rectangle(0, 0, 256, 192); return Rectangle(0, 0, 256, 192);
} }
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override; SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
void Focus(FocusManager& focusManager) void Focus(FocusManager& focusManager)
{ {

View File

@@ -54,9 +54,9 @@ void RomBrowserBottomScreenView::VBlank()
_romBrowserView->VBlank(); _romBrowserView->VBlank();
} }
View* RomBrowserBottomScreenView::MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> RomBrowserBottomScreenView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (currentFocus == nullptr) if (!currentFocus)
{ {
return nullptr; return nullptr;
} }

View File

@@ -6,7 +6,6 @@
#include "../DisplayMode/RomBrowserDisplayMode.h" #include "../DisplayMode/RomBrowserDisplayMode.h"
#include "RomBrowserView.h" #include "RomBrowserView.h"
#include "RomBrowserAppBarView.h" #include "RomBrowserAppBarView.h"
#include "core/SharedPtr.h"
#include "../viewModels/RomBrowserBottomScreenViewModel.h" #include "../viewModels/RomBrowserBottomScreenViewModel.h"
class IRomBrowserViewFactory; class IRomBrowserViewFactory;
@@ -32,7 +31,7 @@ public:
return Rectangle(0, 0, 256, 192); return Rectangle(0, 0, 256, 192);
} }
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override; SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
void Focus(FocusManager& focusManager) void Focus(FocusManager& focusManager)
{ {

View File

@@ -12,11 +12,11 @@
#include "RomBrowserTopScreenView.h" #include "RomBrowserTopScreenView.h"
RomBrowserTopScreenView::RomBrowserTopScreenView( RomBrowserTopScreenView::RomBrowserTopScreenView(
const SharedPtr<RomBrowserViewModel>& viewModel, SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode* displayMode, const RomBrowserDisplayMode* displayMode,
const IThemeFileIconFactory* themeFileIconFactory, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory) const IRomBrowserViewFactory* romBrowserViewFactory)
: _viewModel(viewModel) : _viewModel(std::move(viewModel))
, _themeFileIconFactory(themeFileIconFactory) , _themeFileIconFactory(themeFileIconFactory)
, _fileInfoView(romBrowserViewFactory->CreateFileInfoView()) , _fileInfoView(romBrowserViewFactory->CreateFileInfoView())
, _showCover(displayMode->ShowCoverOnTopScreen()) , _showCover(displayMode->ShowCoverOnTopScreen())

View File

@@ -12,7 +12,7 @@ class IRomBrowserViewFactory;
class RomBrowserTopScreenView : public ViewContainer class RomBrowserTopScreenView : public ViewContainer
{ {
public: public:
RomBrowserTopScreenView(const SharedPtr<RomBrowserViewModel>& viewModel, RomBrowserTopScreenView(SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode* displayMode, const RomBrowserDisplayMode* displayMode,
const IThemeFileIconFactory* themeFileIconFactory, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory); const IRomBrowserViewFactory* romBrowserViewFactory);

View File

@@ -5,12 +5,12 @@
#include "RomBrowserView.h" #include "RomBrowserView.h"
RomBrowserView::RomBrowserView( RomBrowserView::RomBrowserView(
const SharedPtr<RomBrowserViewModel>& viewModel, SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode& displayMode, const RomBrowserDisplayMode& displayMode,
const IThemeFileIconFactory* themeFileIconFactory, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader) VBlankTextureLoader* vblankTextureLoader)
: _viewModel(viewModel), _isVertical(displayMode.IsVertical()) : _viewModel(std::move(viewModel)), _isVertical(displayMode.IsVertical())
{ {
_fileGridView = displayMode.CreateRecyclerView(romBrowserViewFactory); _fileGridView = displayMode.CreateRecyclerView(romBrowserViewFactory);
_fileGridView->SetParent(this); _fileGridView->SetParent(this);
@@ -18,12 +18,6 @@ RomBrowserView::RomBrowserView(
_viewModel.GetPointer(), themeFileIconFactory, romBrowserViewFactory, vblankTextureLoader); _viewModel.GetPointer(), themeFileIconFactory, romBrowserViewFactory, vblankTextureLoader);
} }
RomBrowserView::~RomBrowserView()
{
_fileGridView.reset();
delete _fileRecyclerAdapter;
}
void RomBrowserView::InitVram(const VramContext& vramContext) void RomBrowserView::InitVram(const VramContext& vramContext)
{ {
_fileRecyclerAdapter->InitVram(vramContext); // first initialize the shared vram for the items _fileRecyclerAdapter->InitVram(vramContext); // first initialize the shared vram for the items
@@ -48,9 +42,9 @@ void RomBrowserView::VBlank()
_fileGridView->VBlank(); _fileGridView->VBlank();
} }
View* RomBrowserView::MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) SharedPtr<View> RomBrowserView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{ {
if (currentFocus == nullptr) if (!currentFocus)
{ {
return nullptr; return nullptr;
} }
@@ -72,7 +66,7 @@ View* RomBrowserView::MoveFocus(View* currentFocus, FocusMoveDirection direction
} }
return nullptr; return nullptr;
} }
else if (source == _fileGridView.get()) else if (source == _fileGridView.GetPointer())
{ {
return View::MoveFocus(currentFocus, direction, source); return View::MoveFocus(currentFocus, direction, source);
} }
@@ -83,7 +77,7 @@ bool RomBrowserView::HandleInput(const InputProvider& inputProvider, FocusManage
{ {
if (inputProvider.Triggered(InputKey::A)) if (inputProvider.Triggered(InputKey::A))
{ {
if (focusManager.IsFocusInside(_fileGridView.get())) if (focusManager.IsFocusInside(_fileGridView.GetPointer()))
{ {
_viewModel->ItemActivated(); _viewModel->ItemActivated();
return true; return true;
@@ -91,7 +85,7 @@ bool RomBrowserView::HandleInput(const InputProvider& inputProvider, FocusManage
} }
else if (inputProvider.Triggered(InputKey::Y)) else if (inputProvider.Triggered(InputKey::Y))
{ {
if (focusManager.IsFocusInside(_fileGridView.get())) if (focusManager.IsFocusInside(_fileGridView.GetPointer()))
{ {
_viewModel->ShowGameInfo(); _viewModel->ShowGameInfo();
return true; return true;

View File

@@ -13,14 +13,12 @@ class RomBrowserView : public View
{ {
public: public:
RomBrowserView( RomBrowserView(
const SharedPtr<RomBrowserViewModel>& viewModel, SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode& displayMode, const RomBrowserDisplayMode& displayMode,
const IThemeFileIconFactory* themeFileIconFactory, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory, const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader); VBlankTextureLoader* vblankTextureLoader);
~RomBrowserView();
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
void Update() override; void Update() override;
void Draw(GraphicsContext& graphicsContext) override; void Draw(GraphicsContext& graphicsContext) override;
@@ -40,14 +38,14 @@ public:
return true; return true;
} }
View* MoveFocus( SharedPtr<View> MoveFocus(
View* currentFocus, FocusMoveDirection direction, View* source) override; const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override; bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
private: private:
SharedPtr<RomBrowserViewModel> _viewModel; SharedPtr<RomBrowserViewModel> _viewModel;
std::unique_ptr<RecyclerViewBase> _fileGridView; SharedPtr<RecyclerViewBase> _fileGridView;
FileRecyclerAdapter* _fileRecyclerAdapter; SharedPtr<FileRecyclerAdapter> _fileRecyclerAdapter;
bool _isVertical; bool _isVertical;
}; };

View File

@@ -25,25 +25,20 @@ public:
height = 24; height = 24;
} }
View* CreateView() const override SharedPtr<View> CreateView() const override
{ {
return new CheatListItemView(_vramOffsets, _materialColorScheme, _fontRepository); return SharedPtr<CheatListItemView>::MakeShared(_vramOffsets, _materialColorScheme, _fontRepository);
} }
void DestroyView(View* view) const override void BindView(SharedPtr<View> view, int index) const override
{ {
delete (CheatListItemView*)view; auto listItemView = static_cast<CheatListItemView*>(view.GetPointer());
}
void BindView(View* view, int index) const override
{
auto listItemView = static_cast<CheatListItemView*>(view);
u32 numberOfSubEntries = 0; u32 numberOfSubEntries = 0;
auto subEntries = _cheatCategory->GetSubEntries(numberOfSubEntries); auto subEntries = _cheatCategory->GetSubEntries(numberOfSubEntries);
listItemView->SetEntry(&subEntries[index]); listItemView->SetEntry(&subEntries[index]);
} }
void ReleaseView(View* view, int index) const override void ReleaseView(SharedPtr<View> view, int index) const override
{ {
// Nothing to do // Nothing to do
} }

View File

@@ -37,7 +37,7 @@ CheatsBottomSheetView::CheatsBottomSheetView(std::unique_ptr<CheatsViewModel> vi
, _titleLabel(64, 16, 25, fontRepository->GetFont(FontType::Medium11)) , _titleLabel(64, 16, 25, fontRepository->GetFont(FontType::Medium11))
, _secondaryLabel(177, 16, 64, fontRepository->GetFont(FontType::Regular10)) , _secondaryLabel(177, 16, 64, fontRepository->GetFont(FontType::Regular10))
, _descriptionLabel(224, 16, 256, fontRepository->GetFont(FontType::Medium7_5)) , _descriptionLabel(224, 16, 256, fontRepository->GetFont(FontType::Medium7_5))
, _cheatListRecycler(std::make_unique<RecyclerView>( , _cheatListRecycler(RecyclerView::CreateShared(
LIST_X, LIST_Y, LIST_WIDTH, LIST_HEIGHT, RecyclerView::Mode::VerticalList)) LIST_X, LIST_Y, LIST_WIDTH, LIST_HEIGHT, RecyclerView::Mode::VerticalList))
, _materialColorScheme(materialColorScheme) , _materialColorScheme(materialColorScheme)
, _fontRepository(fontRepository) , _fontRepository(fontRepository)
@@ -51,7 +51,7 @@ CheatsBottomSheetView::CheatsBottomSheetView(std::unique_ptr<CheatsViewModel> vi
AddChildTail(&_titleLabel); AddChildTail(&_titleLabel);
AddChildTail(&_secondaryLabel); AddChildTail(&_secondaryLabel);
AddChildTail(&_descriptionLabel); AddChildTail(&_descriptionLabel);
AddChildTail(_cheatListRecycler.get()); AddChildTail(_cheatListRecycler.GetPointer());
} }
void CheatsBottomSheetView::InitVram(const VramContext& vramContext) void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
@@ -96,9 +96,9 @@ void CheatsBottomSheetView::Update()
_cheatListRecycler->SetPosition(LIST_X, _position.y + LIST_Y); _cheatListRecycler->SetPosition(LIST_X, _position.y + LIST_Y);
if (_viewModel->GetState() == CheatsViewModel::State::DisplayCheats) if (_viewModel->GetState() == CheatsViewModel::State::DisplayCheats)
{ {
if (_cheatsAdapter == nullptr && _objVramManager != nullptr) if (!_cheatsAdapter && _objVramManager != nullptr)
{ {
_cheatsAdapter = new CheatsAdapter( _cheatsAdapter = SharedPtr<CheatsAdapter>::MakeShared(
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets); _viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
_cheatListRecycler->SetAdapter(_cheatsAdapter); _cheatListRecycler->SetAdapter(_cheatsAdapter);
@@ -199,7 +199,7 @@ bool CheatsBottomSheetView::HandleInput(const InputProvider& inputProvider, Focu
{ {
if (inputProvider.Triggered(InputKey::A)) if (inputProvider.Triggered(InputKey::A))
{ {
if (focusManager.IsFocusInside(_cheatListRecycler.get())) if (focusManager.IsFocusInside(_cheatListRecycler.GetPointer()))
{ {
auto oldCategory = _viewModel->GetCurrentCheatCategory(); auto oldCategory = _viewModel->GetCurrentCheatCategory();
_viewModel->ActivateSelectedItem(); _viewModel->ActivateSelectedItem();
@@ -240,11 +240,9 @@ void CheatsBottomSheetView::UpdateCheatList()
// Need to unfocus first, otherwise the focus manager still contains a pointer to a view that is going to be destroyed // Need to unfocus first, otherwise the focus manager still contains a pointer to a view that is going to be destroyed
_focusManager->Unfocus(); _focusManager->Unfocus();
auto oldAdapter = _cheatsAdapter; _cheatsAdapter = SharedPtr<CheatsAdapter>::MakeShared(
_cheatsAdapter = new CheatsAdapter(
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets); _viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
_cheatListRecycler->SetAdapter(_cheatsAdapter, _viewModel->GetSelectedItem()); _cheatListRecycler->SetAdapter(_cheatsAdapter, _viewModel->GetSelectedItem());
delete oldAdapter;
// Ugly hack // Ugly hack
((DescendingStackVramManager*)_objVramManager)->SetState(_savedVramState); ((DescendingStackVramManager*)_objVramManager)->SetState(_savedVramState);

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "core/SharedPtr.h"
#include "romBrowser/views/BottomSheetView.h" #include "romBrowser/views/BottomSheetView.h"
#include "gui/views/Label2DView.h" #include "gui/views/Label2DView.h"
#include "gui/views/RecyclerView.h" #include "gui/views/RecyclerView.h"
@@ -19,15 +20,6 @@ public:
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
FocusManager* focusManager); FocusManager* focusManager);
~CheatsBottomSheetView() override
{
_cheatListRecycler.reset();
if (_cheatsAdapter != nullptr)
{
delete _cheatsAdapter;
}
}
void InitVram(const VramContext& vramContext) override; void InitVram(const VramContext& vramContext) override;
void Update() override; void Update() override;
void Draw(GraphicsContext& graphicsContext) override; void Draw(GraphicsContext& graphicsContext) override;
@@ -43,8 +35,8 @@ private:
Label2DView _titleLabel; Label2DView _titleLabel;
Label2DView _secondaryLabel; Label2DView _secondaryLabel;
Label2DView _descriptionLabel; Label2DView _descriptionLabel;
std::unique_ptr<RecyclerView> _cheatListRecycler; SharedPtr<RecyclerView> _cheatListRecycler;
CheatsAdapter* _cheatsAdapter = nullptr; SharedPtr<CheatsAdapter> _cheatsAdapter;
const MaterialColorScheme* _materialColorScheme; const MaterialColorScheme* _materialColorScheme;
const IFontRepository* _fontRepository; const IFontRepository* _fontRepository;
IVramManager* _objVramManager = nullptr; IVramManager* _objVramManager = nullptr;