mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
Add touch input support, add fast scrolling support for coverflow display mode, fix use after free bug in banner list mode
This commit is contained in:
@@ -20,7 +20,7 @@ class EnableSharedFromThis : public EnableSharedFromThisBase
|
||||
template <class Y>
|
||||
friend class SharedPtr;
|
||||
|
||||
protected:
|
||||
public:
|
||||
SharedPtr<T> SharedFromThis()
|
||||
{
|
||||
return __sharedFromThisWeakPtr.Lock();
|
||||
|
||||
@@ -207,3 +207,10 @@ private:
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define SHARED_ONLY(className) \
|
||||
friend class MakeSharedRefCount<className>; \
|
||||
public: \
|
||||
static SharedPtr<className> CreateShared(auto&&... args) \
|
||||
{ return SharedPtr<className>::MakeShared(std::forward<decltype(args)>(args)...); } \
|
||||
private:
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
constexpr fixed(long double value)
|
||||
: _value(std::round(value * (1 << FractionBits))) { }
|
||||
|
||||
|
||||
constexpr T Int() const
|
||||
{
|
||||
return _value >> FractionBits;
|
||||
@@ -161,11 +161,27 @@ public:
|
||||
return FromRawValue(this->_value >> rhs);
|
||||
}
|
||||
|
||||
constexpr fix16 abs() const
|
||||
constexpr fix16 Abs() const
|
||||
{
|
||||
return FromRawValue(std::abs(this->_value));
|
||||
}
|
||||
|
||||
constexpr fix16 Clamp(fix16 min, fix16 max) const
|
||||
{
|
||||
if (this->_value < min._value)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
else if (this->_value > max._value)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
@@ -265,21 +281,45 @@ public:
|
||||
return this->_value < other._value;
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend bool operator<(TLhs lhs, const fix32& rhs)
|
||||
{
|
||||
return fix32(lhs)._value < rhs._value;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const fix32& other) const
|
||||
{
|
||||
return this->_value <= other._value;
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend bool operator<=(TLhs lhs, const fix32& rhs)
|
||||
{
|
||||
return fix32(lhs)._value <= rhs._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const fix32& other) const
|
||||
{
|
||||
return this->_value > other._value;
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend bool operator>(TLhs lhs, const fix32& rhs)
|
||||
{
|
||||
return fix32(lhs)._value > rhs._value;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const fix32& other) const
|
||||
{
|
||||
return this->_value >= other._value;
|
||||
}
|
||||
|
||||
template <typename TLhs>
|
||||
constexpr friend bool operator>=(TLhs lhs, const fix32& rhs)
|
||||
{
|
||||
return fix32(lhs)._value >= rhs._value;
|
||||
}
|
||||
|
||||
constexpr fix32 operator-() const
|
||||
{
|
||||
return FromRawValue(-this->_value);
|
||||
@@ -337,6 +377,22 @@ public:
|
||||
return FromRawValue(std::abs(this->_value));
|
||||
}
|
||||
|
||||
constexpr fix32 Clamp(fix32 min, fix32 max) const
|
||||
{
|
||||
if (this->_value < min._value)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
else if (this->_value > max._value)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix64<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
@@ -354,6 +410,11 @@ public:
|
||||
return fix64<FractionBits>::FromRawValue((s64)this->_value * other);
|
||||
}
|
||||
|
||||
constexpr fix64<FractionBits> LongMul(double other) const
|
||||
{
|
||||
return LongMul(fix32(other));
|
||||
}
|
||||
|
||||
template <u32 OtherFractionBits>
|
||||
constexpr fix32 operator*(const fix16<OtherFractionBits>& other) const
|
||||
{
|
||||
@@ -371,6 +432,11 @@ public:
|
||||
return FromRawValue(this->_value * other);
|
||||
}
|
||||
|
||||
constexpr fix32 operator*(double other) const
|
||||
{
|
||||
return fix32(LongMul(fix32(other)));
|
||||
}
|
||||
|
||||
constexpr friend fix32 operator*(int lhs, const fix32& rhs)
|
||||
{
|
||||
return FromRawValue(lhs * rhs.GetRawValue());
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
#include "common.h"
|
||||
#include "Task.h"
|
||||
|
||||
void TaskBase::Execute()
|
||||
void TaskBase::RequestCancel()
|
||||
{
|
||||
u32 irqs = rtos_disableIrqs();
|
||||
_cancelRequested = true;
|
||||
if (_state == TaskState::NotStarted)
|
||||
{
|
||||
_state = TaskState::Canceled;
|
||||
rtos_wakeupQueue(&_threadQueue);
|
||||
}
|
||||
rtos_restoreIrqs(irqs);
|
||||
}
|
||||
|
||||
void TaskBase::Execute(u32 irqs)
|
||||
{
|
||||
if (_state == TaskState::NotStarted)
|
||||
{
|
||||
_state = TaskState::Running;
|
||||
@@ -12,7 +23,9 @@ void TaskBase::Execute()
|
||||
SetFinalState(finalState);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtos_restoreIrqs(irqs);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskBase::SetFinalState(TaskState finalState)
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
#include <memory>
|
||||
#include <libtwl/rtos/rtosIrq.h>
|
||||
#include <libtwl/rtos/rtosThread.h>
|
||||
#include "core/LinkedListLink.h"
|
||||
#include "TaskResult.h"
|
||||
|
||||
class TaskBase
|
||||
{
|
||||
public:
|
||||
LinkedListLink link;
|
||||
|
||||
virtual ~TaskBase() { }
|
||||
|
||||
void Execute();
|
||||
void Execute(u32 irqs);
|
||||
|
||||
TaskState GetState() const { return _state; }
|
||||
|
||||
@@ -24,7 +27,7 @@ public:
|
||||
bool GetDestroyWhenComplete() const { return _destroyWhenComplete; }
|
||||
void SetDestroyWhenComplete() { _destroyWhenComplete = true; }
|
||||
|
||||
void RequestCancel() { _cancelRequested = true; }
|
||||
void RequestCancel();
|
||||
bool IsCancelRequested() const { return _cancelRequested; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
#include "common.h"
|
||||
#include "TaskQueue.h"
|
||||
|
||||
void TaskQueueBase::ThreadMain(TaskBase** queue, u32 queueLength)
|
||||
void TaskQueueBase::ThreadMain()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
_idle = false;
|
||||
u32 readPtr = _queueReadPtr;
|
||||
while (readPtr != _queueWritePtr)
|
||||
while (true)
|
||||
{
|
||||
TaskBase* task = queue[readPtr];
|
||||
if (readPtr == queueLength - 1)
|
||||
readPtr = 0;
|
||||
else
|
||||
readPtr++;
|
||||
_queueReadPtr = readPtr;
|
||||
u32 irqs = rtos_disableIrqs();
|
||||
auto task = _taskList.GetHead();
|
||||
if (!task)
|
||||
continue;
|
||||
task->Execute();
|
||||
{
|
||||
rtos_restoreIrqs(irqs);
|
||||
break;
|
||||
}
|
||||
_taskList.Remove(task);
|
||||
task->Execute(irqs);
|
||||
if (task->GetDestroyWhenComplete())
|
||||
{
|
||||
// this will destroy the task
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <libtwl/rtos/rtosEvent.h>
|
||||
#include <libtwl/rtos/rtosThread.h>
|
||||
#include "core/BitVector.h"
|
||||
#include "core/LinkedList.h"
|
||||
#include "Task.h"
|
||||
|
||||
class TaskQueueBase;
|
||||
@@ -11,25 +12,13 @@ class TaskQueueBase;
|
||||
class QueueTaskBase
|
||||
{
|
||||
public:
|
||||
// forbid copies
|
||||
QueueTaskBase(const QueueTaskBase&) = delete;
|
||||
QueueTaskBase& operator=(const QueueTaskBase&) = delete;
|
||||
|
||||
// move assignment
|
||||
QueueTaskBase& operator=(QueueTaskBase&& other)
|
||||
{
|
||||
_taskQueue = other._taskQueue;
|
||||
_task = other._task;
|
||||
other._taskQueue = nullptr;
|
||||
other._task = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~QueueTaskBase()
|
||||
{
|
||||
// extra check here for optimizing out the dispose call after move assignment
|
||||
if (_task)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void Dispose();
|
||||
@@ -47,12 +36,10 @@ public:
|
||||
|
||||
protected:
|
||||
TaskBase* _task;
|
||||
TaskQueueBase* _taskQueue;
|
||||
|
||||
QueueTaskBase(TaskBase* task, TaskQueueBase* taskQueue)
|
||||
: _task(task), _taskQueue(taskQueue) { }
|
||||
|
||||
private:
|
||||
TaskQueueBase* _taskQueue;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -62,6 +49,26 @@ public:
|
||||
QueueTask()
|
||||
: QueueTaskBase(nullptr, nullptr) { }
|
||||
|
||||
QueueTask(const QueueTask&) = delete;
|
||||
QueueTask& operator=(const QueueTask&) = delete;
|
||||
|
||||
QueueTask(QueueTask&& other)
|
||||
: QueueTaskBase(other._task, other._taskQueue)
|
||||
{
|
||||
other._task = nullptr;
|
||||
other._taskQueue = nullptr;
|
||||
}
|
||||
|
||||
QueueTask& operator=(QueueTask&& other)
|
||||
{
|
||||
Dispose();
|
||||
_taskQueue = other._taskQueue;
|
||||
_task = other._task;
|
||||
other._taskQueue = nullptr;
|
||||
other._task = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
QueueTask(Task<T>* task, TaskQueueBase* taskQueue)
|
||||
: QueueTaskBase(task, taskQueue) { }
|
||||
|
||||
@@ -91,12 +98,11 @@ public:
|
||||
|
||||
protected:
|
||||
rtos_event_t _event;
|
||||
vu32 _queueReadPtr = 0;
|
||||
vu32 _queueWritePtr = 0;
|
||||
LinkedList<TaskBase, &TaskBase::link> _taskList;
|
||||
volatile bool _endThreadWhenDone = false;
|
||||
volatile bool _idle = true;
|
||||
|
||||
void ThreadMain(TaskBase** queue, u32 queueLength);
|
||||
void ThreadMain();
|
||||
|
||||
TaskQueueBase()
|
||||
{
|
||||
@@ -124,6 +130,10 @@ public:
|
||||
u32 irqs = rtos_disableIrqs();
|
||||
if (task->IsCompleted())
|
||||
{
|
||||
if (task->link.prev != nullptr || task->link.next != nullptr)
|
||||
{
|
||||
_taskList.Remove(task);
|
||||
}
|
||||
task->~TaskBase();
|
||||
u32 slot = ((u32)task - (u32)_taskPool) / ((MaxTaskSize + 3) & ~3);
|
||||
_poolOccupation.Set(slot, 0);
|
||||
@@ -159,13 +169,12 @@ public:
|
||||
|
||||
bool IsIdle() const
|
||||
{
|
||||
return _queueReadPtr == _queueWritePtr && _idle;
|
||||
return _taskList.GetHead() == nullptr && _idle;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 _taskPool[QueueLength][(MaxTaskSize + 3) / 4];
|
||||
BitVector<QueueLength> _poolOccupation;
|
||||
TaskBase* _queue[QueueLength];
|
||||
rtos_thread_t _thread;
|
||||
bool _threadStarted = false;
|
||||
|
||||
@@ -191,12 +200,11 @@ private:
|
||||
[[gnu::noinline]]
|
||||
void Enqueue(TaskBase* task) override
|
||||
{
|
||||
u32 writePtr = _queueWritePtr;
|
||||
_queue[writePtr] = task;
|
||||
if (writePtr == QueueLength - 1)
|
||||
_queueWritePtr = 0;
|
||||
else
|
||||
_queueWritePtr = writePtr + 1;
|
||||
u32 irqs = rtos_disableIrqs();
|
||||
{
|
||||
_taskList.InsertTail(task);
|
||||
}
|
||||
rtos_restoreIrqs(irqs);
|
||||
rtos_signalEvent(&_event);
|
||||
}
|
||||
|
||||
@@ -207,6 +215,6 @@ private:
|
||||
|
||||
void ThreadMain()
|
||||
{
|
||||
TaskQueueBase::ThreadMain(&_queue[0], QueueLength);
|
||||
TaskQueueBase::ThreadMain();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user