mirror of
https://github.com/hyprwm/hyprutils.git
synced 2025-12-20 07:00:10 +01:00
Compare commits
12 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ac060bfcf | ||
| 1c527b30fe | |||
| fe686486ac | |||
| 2f2413801b | |||
|
|
9f8e158dbd | ||
|
|
7e6346f84b | ||
|
|
a64517c236 | ||
| 0168583075 | |||
| 5e1a14bc29 | |||
| bc9803c4b8 | |||
|
|
44c2ba0354 | ||
| 96df6f6535 |
17 changed files with 309 additions and 85 deletions
|
|
@ -52,7 +52,7 @@ target_include_directories(
|
||||||
PUBLIC "./include"
|
PUBLIC "./include"
|
||||||
PRIVATE "./src")
|
PRIVATE "./src")
|
||||||
set_target_properties(hyprutils PROPERTIES VERSION ${hyprutils_VERSION}
|
set_target_properties(hyprutils PROPERTIES VERSION ${hyprutils_VERSION}
|
||||||
SOVERSION 9)
|
SOVERSION 10)
|
||||||
target_link_libraries(hyprutils PkgConfig::deps)
|
target_link_libraries(hyprutils PkgConfig::deps)
|
||||||
|
|
||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
|
|
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
0.10.3
|
0.11.0
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ namespace Hyprutils {
|
||||||
};
|
};
|
||||||
|
|
||||||
void create(CAnimationManager*, int, Memory::CSharedPointer<CBaseAnimatedVariable>);
|
void create(CAnimationManager*, int, Memory::CSharedPointer<CBaseAnimatedVariable>);
|
||||||
|
void create2(CAnimationManager*, int, Memory::CWeakPointer<CBaseAnimatedVariable>);
|
||||||
void connectToActive();
|
void connectToActive();
|
||||||
void disconnectFromActive();
|
void disconnectFromActive();
|
||||||
|
|
||||||
|
|
@ -136,6 +137,7 @@ namespace Hyprutils {
|
||||||
public:
|
public:
|
||||||
CGenericAnimatedVariable() = default;
|
CGenericAnimatedVariable() = default;
|
||||||
|
|
||||||
|
/* Deprecated: use create2 */
|
||||||
void create(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf,
|
void create(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf,
|
||||||
const VarType& initialValue) {
|
const VarType& initialValue) {
|
||||||
m_Begun = initialValue;
|
m_Begun = initialValue;
|
||||||
|
|
@ -145,6 +147,16 @@ namespace Hyprutils {
|
||||||
CBaseAnimatedVariable::create(pAnimationManager, typeInfo, pSelf);
|
CBaseAnimatedVariable::create(pAnimationManager, typeInfo, pSelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Equivalent to create, except that it allows animated variables to be UP's */
|
||||||
|
void create2(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CWeakPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf,
|
||||||
|
const VarType& initialValue) {
|
||||||
|
m_Begun = initialValue;
|
||||||
|
m_Value = initialValue;
|
||||||
|
m_Goal = initialValue;
|
||||||
|
|
||||||
|
CBaseAnimatedVariable::create2(pAnimationManager, typeInfo, pSelf);
|
||||||
|
}
|
||||||
|
|
||||||
CGenericAnimatedVariable(const CGenericAnimatedVariable&) = delete;
|
CGenericAnimatedVariable(const CGenericAnimatedVariable&) = delete;
|
||||||
CGenericAnimatedVariable(CGenericAnimatedVariable&&) = delete;
|
CGenericAnimatedVariable(CGenericAnimatedVariable&&) = delete;
|
||||||
CGenericAnimatedVariable& operator=(const CGenericAnimatedVariable&) = delete;
|
CGenericAnimatedVariable& operator=(const CGenericAnimatedVariable&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,13 @@ namespace Hyprutils::CLI {
|
||||||
// Allow move
|
// Allow move
|
||||||
CLoggerConnection(CLoggerConnection&&) = default;
|
CLoggerConnection(CLoggerConnection&&) = default;
|
||||||
|
|
||||||
void setName(const std::string_view& name);
|
void setName(const std::string_view& name);
|
||||||
void setLogLevel(eLogLevel level);
|
void setLogLevel(eLogLevel level);
|
||||||
|
|
||||||
void log(eLogLevel level, const std::string_view& msg);
|
void log(eLogLevel level, const std::string_view& msg);
|
||||||
|
|
||||||
|
CLogger* getLogger();
|
||||||
|
void redirect(CLogger& logger);
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
// NOLINTNEXTLINE
|
// NOLINTNEXTLINE
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,11 @@ namespace Hyprutils::Memory {
|
||||||
using validHierarchy = std::enable_if_t<std::is_assignable_v<CAtomicSharedPointer<T>&, X>, CAtomicSharedPointer&>;
|
using validHierarchy = std::enable_if_t<std::is_assignable_v<CAtomicSharedPointer<T>&, X>, CAtomicSharedPointer&>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CAtomicSharedPointer(T* object) noexcept : m_ptr(new Atomic_::impl(sc<void*>(object), _delete)) {
|
explicit CAtomicSharedPointer(T* object) noexcept : m_ptr(new Atomic_::impl(sc<void*>(object), _delete), sc<void*>(object)) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAtomicSharedPointer(Impl_::impl_base* impl) noexcept : m_ptr(impl) {
|
CAtomicSharedPointer(Impl_::impl_base* impl, void* data) noexcept : m_ptr(impl, data) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,13 +219,17 @@ namespace Hyprutils::Memory {
|
||||||
return m_ptr.impl_ ? m_ptr.impl_->ref() : 0;
|
return m_ptr.impl_ ? m_ptr.impl_->ref() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Atomic_::impl* impl() const {
|
||||||
|
return sc<Atomic_::impl*>(m_ptr.impl_);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _delete(void* p) {
|
static void _delete(void* p) {
|
||||||
std::default_delete<T>{}(sc<T*>(p));
|
std::default_delete<T>{}(sc<T*>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> implLockGuard() const {
|
std::lock_guard<std::recursive_mutex> implLockGuard() const {
|
||||||
return sc<Atomic_::impl*>(m_ptr.impl_)->lockGuard();
|
return impl()->lockGuard();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharedPointer<T> m_ptr;
|
CSharedPointer<T> m_ptr;
|
||||||
|
|
@ -391,12 +395,16 @@ namespace Hyprutils::Memory {
|
||||||
if (!m_ptr.impl_->dataNonNull() || m_ptr.impl_->destroying() || !m_ptr.impl_->lockable())
|
if (!m_ptr.impl_->dataNonNull() || m_ptr.impl_->destroying() || !m_ptr.impl_->lockable())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return CAtomicSharedPointer<T>(m_ptr.impl_);
|
return CAtomicSharedPointer<T>(m_ptr.impl_, m_ptr.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Atomic_::impl* impl() const {
|
||||||
|
return sc<Atomic_::impl*>(m_ptr.impl_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::lock_guard<std::recursive_mutex> implLockGuard() const {
|
std::lock_guard<std::recursive_mutex> implLockGuard() const {
|
||||||
return sc<Atomic_::impl*>(m_ptr.impl_)->lockGuard();
|
return impl()->lockGuard();
|
||||||
}
|
}
|
||||||
|
|
||||||
CWeakPointer<T> m_ptr;
|
CWeakPointer<T> m_ptr;
|
||||||
|
|
@ -411,4 +419,19 @@ namespace Hyprutils::Memory {
|
||||||
[[nodiscard]] inline CAtomicSharedPointer<U> makeAtomicShared(Args&&... args) {
|
[[nodiscard]] inline CAtomicSharedPointer<U> makeAtomicShared(Args&&... args) {
|
||||||
return CAtomicSharedPointer<U>(new U(std::forward<Args>(args)...));
|
return CAtomicSharedPointer<U>(new U(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
CAtomicSharedPointer<T> reinterpretPointerCast(const CAtomicSharedPointer<U>& ref) {
|
||||||
|
return CAtomicSharedPointer<T>(ref.impl(), ref.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
CAtomicSharedPointer<T> dynamicPointerCast(const CAtomicSharedPointer<U>& ref) {
|
||||||
|
if (!ref)
|
||||||
|
return nullptr;
|
||||||
|
T* newPtr = dynamic_cast<T*>(sc<U*>(ref.impl()->getData()));
|
||||||
|
if (!newPtr)
|
||||||
|
return nullptr;
|
||||||
|
return CAtomicSharedPointer<T>(ref.impl(), newPtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,31 +28,33 @@ namespace Hyprutils {
|
||||||
|
|
||||||
/* creates a new shared pointer managing a resource
|
/* creates a new shared pointer managing a resource
|
||||||
avoid calling. Could duplicate ownership. Prefer makeShared */
|
avoid calling. Could duplicate ownership. Prefer makeShared */
|
||||||
explicit CSharedPointer(T* object) noexcept : impl_(new Impl_::impl_base(sc<void*>(object), _delete)) {
|
explicit CSharedPointer(T* object) noexcept : impl_(new Impl_::impl_base(sc<void*>(object), _delete)), m_data(sc<void*>(object)) {
|
||||||
increment();
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* creates a shared pointer from a reference */
|
/* creates a shared pointer from a reference */
|
||||||
template <typename U, typename = isConstructible<U>>
|
template <typename U, typename = isConstructible<U>>
|
||||||
CSharedPointer(const CSharedPointer<U>& ref) noexcept : impl_(ref.impl_) {
|
CSharedPointer(const CSharedPointer<U>& ref) noexcept : impl_(ref.impl_), m_data(ref.m_data) {
|
||||||
increment();
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharedPointer(const CSharedPointer& ref) noexcept : impl_(ref.impl_) {
|
CSharedPointer(const CSharedPointer& ref) noexcept : impl_(ref.impl_), m_data(ref.m_data) {
|
||||||
increment();
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U, typename = isConstructible<U>>
|
template <typename U, typename = isConstructible<U>>
|
||||||
CSharedPointer(CSharedPointer<U>&& ref) noexcept {
|
CSharedPointer(CSharedPointer<U>&& ref) noexcept {
|
||||||
std::swap(impl_, ref.impl_);
|
std::swap(impl_, ref.impl_);
|
||||||
|
std::swap(m_data, ref.m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharedPointer(CSharedPointer&& ref) noexcept {
|
CSharedPointer(CSharedPointer&& ref) noexcept {
|
||||||
std::swap(impl_, ref.impl_);
|
std::swap(impl_, ref.impl_);
|
||||||
|
std::swap(m_data, ref.m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allows weakPointer to create from an impl */
|
/* allows weakPointer to create from an impl */
|
||||||
CSharedPointer(Impl_::impl_base* implementation) noexcept : impl_(implementation) {
|
CSharedPointer(Impl_::impl_base* implementation, void* data) noexcept : impl_(implementation), m_data(data) {
|
||||||
increment();
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +76,8 @@ namespace Hyprutils {
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
decrement();
|
decrement();
|
||||||
impl_ = rhs.impl_;
|
impl_ = rhs.impl_;
|
||||||
|
m_data = rhs.m_data;
|
||||||
increment();
|
increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +87,8 @@ namespace Hyprutils {
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
decrement();
|
decrement();
|
||||||
impl_ = rhs.impl_;
|
impl_ = rhs.impl_;
|
||||||
|
m_data = rhs.m_data;
|
||||||
increment();
|
increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -92,11 +96,13 @@ namespace Hyprutils {
|
||||||
template <typename U>
|
template <typename U>
|
||||||
validHierarchy<const CSharedPointer<U>&> operator=(CSharedPointer<U>&& rhs) {
|
validHierarchy<const CSharedPointer<U>&> operator=(CSharedPointer<U>&& rhs) {
|
||||||
std::swap(impl_, rhs.impl_);
|
std::swap(impl_, rhs.impl_);
|
||||||
|
std::swap(m_data, rhs.m_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharedPointer& operator=(CSharedPointer&& rhs) noexcept {
|
CSharedPointer& operator=(CSharedPointer&& rhs) noexcept {
|
||||||
std::swap(impl_, rhs.impl_);
|
std::swap(impl_, rhs.impl_);
|
||||||
|
std::swap(m_data, rhs.m_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,6 +110,8 @@ namespace Hyprutils {
|
||||||
return impl_ && impl_->dataNonNull();
|
return impl_ && impl_->dataNonNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this compares that the pointed-to object is the same, but in multiple inheritance,
|
||||||
|
// different typed pointers can be equal if the object is the same
|
||||||
bool operator==(const CSharedPointer& rhs) const {
|
bool operator==(const CSharedPointer& rhs) const {
|
||||||
return impl_ == rhs.impl_;
|
return impl_ == rhs.impl_;
|
||||||
}
|
}
|
||||||
|
|
@ -126,11 +134,12 @@ namespace Hyprutils {
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
decrement();
|
decrement();
|
||||||
impl_ = nullptr;
|
impl_ = nullptr;
|
||||||
|
m_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get() const {
|
T* get() const {
|
||||||
return impl_ ? sc<T*>(impl_->getData()) : nullptr;
|
return impl_ && impl_->dataNonNull() ? sc<T*>(m_data) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int strongRef() const {
|
unsigned int strongRef() const {
|
||||||
|
|
@ -139,6 +148,9 @@ namespace Hyprutils {
|
||||||
|
|
||||||
Impl_::impl_base* impl_ = nullptr;
|
Impl_::impl_base* impl_ = nullptr;
|
||||||
|
|
||||||
|
// Never use directly: raw data ptr, could be UAF
|
||||||
|
void* m_data = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _delete(void* p) {
|
static void _delete(void* p) {
|
||||||
std::default_delete<T>{}(sc<T*>(p));
|
std::default_delete<T>{}(sc<T*>(p));
|
||||||
|
|
@ -188,7 +200,17 @@ namespace Hyprutils {
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
CSharedPointer<T> reinterpretPointerCast(const CSharedPointer<U>& ref) {
|
CSharedPointer<T> reinterpretPointerCast(const CSharedPointer<U>& ref) {
|
||||||
return CSharedPointer<T>(ref.impl_);
|
return CSharedPointer<T>(ref.impl_, ref.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
CSharedPointer<T> dynamicPointerCast(const CSharedPointer<U>& ref) {
|
||||||
|
if (!ref)
|
||||||
|
return nullptr;
|
||||||
|
T* newPtr = dynamic_cast<T*>(sc<U*>(ref.impl_->getData()));
|
||||||
|
if (!newPtr)
|
||||||
|
return nullptr;
|
||||||
|
return CSharedPointer<T>(ref.impl_, newPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ namespace Hyprutils {
|
||||||
if (!ref.impl_)
|
if (!ref.impl_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
impl_ = ref.impl_;
|
impl_ = ref.impl_;
|
||||||
|
m_data = ref.m_data;
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +37,8 @@ namespace Hyprutils {
|
||||||
if (!ref.impl_)
|
if (!ref.impl_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
impl_ = ref.impl_;
|
impl_ = ref.impl_;
|
||||||
|
m_data = ref.impl_->getData();
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,7 +48,8 @@ namespace Hyprutils {
|
||||||
if (!ref.impl_)
|
if (!ref.impl_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
impl_ = ref.impl_;
|
impl_ = ref.impl_;
|
||||||
|
m_data = ref.m_data;
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,17 +57,20 @@ namespace Hyprutils {
|
||||||
if (!ref.impl_)
|
if (!ref.impl_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
impl_ = ref.impl_;
|
impl_ = ref.impl_;
|
||||||
|
m_data = ref.m_data;
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U, typename = isConstructible<U>>
|
template <typename U, typename = isConstructible<U>>
|
||||||
CWeakPointer(CWeakPointer<U>&& ref) noexcept {
|
CWeakPointer(CWeakPointer<U>&& ref) noexcept {
|
||||||
std::swap(impl_, ref.impl_);
|
std::swap(impl_, ref.impl_);
|
||||||
|
std::swap(m_data, ref.m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
CWeakPointer(CWeakPointer&& ref) noexcept {
|
CWeakPointer(CWeakPointer&& ref) noexcept {
|
||||||
std::swap(impl_, ref.impl_);
|
std::swap(impl_, ref.impl_);
|
||||||
|
std::swap(m_data, ref.m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a weak ptr from another weak ptr with assignment */
|
/* create a weak ptr from another weak ptr with assignment */
|
||||||
|
|
@ -74,7 +80,8 @@ namespace Hyprutils {
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
decrementWeak();
|
decrementWeak();
|
||||||
impl_ = rhs.impl_;
|
impl_ = rhs.impl_;
|
||||||
|
m_data = rhs.m_data;
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +91,8 @@ namespace Hyprutils {
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
decrementWeak();
|
decrementWeak();
|
||||||
impl_ = rhs.impl_;
|
impl_ = rhs.impl_;
|
||||||
|
m_data = rhs.m_data;
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +104,8 @@ namespace Hyprutils {
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
decrementWeak();
|
decrementWeak();
|
||||||
impl_ = rhs.impl_;
|
impl_ = rhs.impl_;
|
||||||
|
m_data = rhs.m_data;
|
||||||
incrementWeak();
|
incrementWeak();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -125,14 +134,15 @@ namespace Hyprutils {
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
decrementWeak();
|
decrementWeak();
|
||||||
impl_ = nullptr;
|
impl_ = nullptr;
|
||||||
|
m_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharedPointer<T> lock() const {
|
CSharedPointer<T> lock() const {
|
||||||
if (!impl_ || !impl_->dataNonNull() || impl_->destroying() || !impl_->lockable())
|
if (!impl_ || !impl_->dataNonNull() || impl_->destroying() || !impl_->lockable())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return CSharedPointer<T>(impl_);
|
return CSharedPointer<T>(impl_, m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this returns valid() */
|
/* this returns valid() */
|
||||||
|
|
@ -169,7 +179,7 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get() const {
|
T* get() const {
|
||||||
return impl_ ? sc<T*>(impl_->getData()) : nullptr;
|
return impl_ && impl_->dataNonNull() ? sc<T*>(m_data) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* operator->() const {
|
T* operator->() const {
|
||||||
|
|
@ -182,6 +192,9 @@ namespace Hyprutils {
|
||||||
|
|
||||||
Impl_::impl_base* impl_ = nullptr;
|
Impl_::impl_base* impl_ = nullptr;
|
||||||
|
|
||||||
|
// Never use directly: raw data ptr, could be UAF
|
||||||
|
void* m_data = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* no-op if there is no impl_ */
|
/* no-op if there is no impl_ */
|
||||||
void decrementWeak() {
|
void decrementWeak() {
|
||||||
|
|
@ -207,6 +220,16 @@ namespace Hyprutils {
|
||||||
impl_->incWeak();
|
impl_->incWeak();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
CWeakPointer<T> dynamicPointerCast(const CWeakPointer<U>& ref) {
|
||||||
|
if (!ref)
|
||||||
|
return nullptr;
|
||||||
|
T* newPtr = dynamic_cast<T*>(sc<U*>(ref.impl_->getData()));
|
||||||
|
if (!newPtr)
|
||||||
|
return nullptr;
|
||||||
|
return CWeakPointer<T>(ref.impl_, newPtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,13 @@ namespace Hyprutils {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
class CSignalT : public CSignalBase {
|
class CSignalT : public CSignalBase {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using RefArg = std::conditional_t<std::is_reference_v<T> || std::is_arithmetic_v<T>, T, const T&>;
|
using RefArg = std::conditional_t<std::is_trivially_copyable_v<T>, T, const T&>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void emit(RefArg<Args>... args) {
|
void emit(RefArg<Args>... args) {
|
||||||
|
if (m_vListeners.empty() && m_vStaticListeners.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
if constexpr (sizeof...(Args) == 0)
|
if constexpr (sizeof...(Args) == 0)
|
||||||
emitInternal(nullptr);
|
emitInternal(nullptr);
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,16 @@ static const std::string DEFAULTSTYLE = "";
|
||||||
|
|
||||||
void CBaseAnimatedVariable::create(CAnimationManager* pManager, int typeInfo, SP<CBaseAnimatedVariable> pSelf) {
|
void CBaseAnimatedVariable::create(CAnimationManager* pManager, int typeInfo, SP<CBaseAnimatedVariable> pSelf) {
|
||||||
m_Type = typeInfo;
|
m_Type = typeInfo;
|
||||||
m_pSelf = pSelf;
|
m_pSelf = std::move(pSelf);
|
||||||
|
|
||||||
|
m_pAnimationManager = pManager;
|
||||||
|
m_pSignals = pManager->getSignals();
|
||||||
|
m_bDummy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBaseAnimatedVariable::create2(CAnimationManager* pManager, int typeInfo, WP<CBaseAnimatedVariable> pSelf) {
|
||||||
|
m_Type = typeInfo;
|
||||||
|
m_pSelf = std::move(pSelf);
|
||||||
|
|
||||||
m_pAnimationManager = pManager;
|
m_pAnimationManager = pManager;
|
||||||
m_pSignals = pManager->getSignals();
|
m_pSignals = pManager->getSignals();
|
||||||
|
|
@ -37,28 +46,22 @@ void CBaseAnimatedVariable::disconnectFromActive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hyprutils::Animation::CBaseAnimatedVariable::enabled() const {
|
bool Hyprutils::Animation::CBaseAnimatedVariable::enabled() const {
|
||||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
if (m_pConfig && m_pConfig->pValues)
|
||||||
const auto PVALUES = PCONFIG->pValues.lock();
|
return m_pConfig->pValues->internalEnabled;
|
||||||
return PVALUES ? PVALUES->internalEnabled : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& CBaseAnimatedVariable::getBezierName() const {
|
const std::string& CBaseAnimatedVariable::getBezierName() const {
|
||||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
if (m_pConfig && m_pConfig->pValues)
|
||||||
const auto PVALUES = PCONFIG->pValues.lock();
|
return m_pConfig->pValues->internalBezier;
|
||||||
return PVALUES ? PVALUES->internalBezier : DEFAULTBEZIERNAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEFAULTBEZIERNAME;
|
return DEFAULTBEZIERNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& CBaseAnimatedVariable::getStyle() const {
|
const std::string& CBaseAnimatedVariable::getStyle() const {
|
||||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
if (m_pConfig && m_pConfig->pValues)
|
||||||
const auto PVALUES = PCONFIG->pValues.lock();
|
return m_pConfig->pValues->internalStyle;
|
||||||
return PVALUES ? PVALUES->internalStyle : DEFAULTSTYLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEFAULTSTYLE;
|
return DEFAULTSTYLE;
|
||||||
}
|
}
|
||||||
|
|
@ -66,10 +69,8 @@ const std::string& CBaseAnimatedVariable::getStyle() const {
|
||||||
float CBaseAnimatedVariable::getPercent() const {
|
float CBaseAnimatedVariable::getPercent() const {
|
||||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - animationBegin).count();
|
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - animationBegin).count();
|
||||||
|
|
||||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
if (m_pConfig && m_pConfig->pValues)
|
||||||
const auto PVALUES = PCONFIG->pValues.lock();
|
return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f);
|
||||||
return PVALUES ? std::clamp((DURATIONPASSED / 100.f) / PVALUES->internalSpeed, 0.f, 1.f) : 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
|
|
@ -78,14 +79,7 @@ float CBaseAnimatedVariable::getCurveValue() const {
|
||||||
if (!m_bIsBeingAnimated || isAnimationManagerDead())
|
if (!m_bIsBeingAnimated || isAnimationManagerDead())
|
||||||
return 1.f;
|
return 1.f;
|
||||||
|
|
||||||
std::string bezierName = "";
|
const auto BEZIER = m_pAnimationManager->getBezier(getBezierName());
|
||||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
|
||||||
const auto PVALUES = PCONFIG->pValues.lock();
|
|
||||||
if (PVALUES)
|
|
||||||
bezierName = PVALUES->internalBezier;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto BEZIER = m_pAnimationManager->getBezier(bezierName);
|
|
||||||
if (!BEZIER)
|
if (!BEZIER)
|
||||||
return 1.f;
|
return 1.f;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,14 +64,13 @@ void CAnimationManager::rotateActive() {
|
||||||
std::vector<CWeakPointer<CBaseAnimatedVariable>> active;
|
std::vector<CWeakPointer<CBaseAnimatedVariable>> active;
|
||||||
active.reserve(m_vActiveAnimatedVariables.size()); // avoid reallocations
|
active.reserve(m_vActiveAnimatedVariables.size()); // avoid reallocations
|
||||||
for (auto const& av : m_vActiveAnimatedVariables) {
|
for (auto const& av : m_vActiveAnimatedVariables) {
|
||||||
const auto PAV = av.lock();
|
if (!av)
|
||||||
if (!PAV)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (PAV->ok() && PAV->isBeingAnimated())
|
if (av->ok() && av->isBeingAnimated())
|
||||||
active.emplace_back(av);
|
active.emplace_back(av);
|
||||||
else
|
else
|
||||||
PAV->m_bIsConnectedToActive = false;
|
av->m_bIsConnectedToActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vActiveAnimatedVariables = std::move(active);
|
m_vActiveAnimatedVariables = std::move(active);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <hyprutils/string/String.hpp>
|
#include <hyprutils/string/String.hpp>
|
||||||
#include <hyprutils/memory/Casts.hpp>
|
#include <hyprutils/memory/Casts.hpp>
|
||||||
|
|
@ -95,12 +96,17 @@ CArgumentParserImpl::CArgumentParserImpl(const std::span<const char*>& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SArgumentKey>::iterator CArgumentParserImpl::getValue(const std::string_view& sv) {
|
std::vector<SArgumentKey>::iterator CArgumentParserImpl::getValue(const std::string_view& sv) {
|
||||||
|
if (sv.empty())
|
||||||
|
return m_values.end();
|
||||||
auto it = std::ranges::find_if(m_values, [&sv](const auto& e) { return e.full == sv || e.abbrev == sv; });
|
auto it = std::ranges::find_if(m_values, [&sv](const auto& e) { return e.full == sv || e.abbrev == sv; });
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<void, std::string> CArgumentParserImpl::registerOption(const std::string_view& name, const std::string_view& abbrev, const std::string_view& description,
|
std::expected<void, std::string> CArgumentParserImpl::registerOption(const std::string_view& name, const std::string_view& abbrev, const std::string_view& description,
|
||||||
eArgumentType type) {
|
eArgumentType type) {
|
||||||
|
if (name.empty())
|
||||||
|
return std::unexpected("Name cannot be empty");
|
||||||
|
|
||||||
if (getValue(name) != m_values.end() || getValue(abbrev) != m_values.end())
|
if (getValue(name) != m_values.end() || getValue(abbrev) != m_values.end())
|
||||||
return std::unexpected("Value already exists");
|
return std::unexpected("Value already exists");
|
||||||
|
|
||||||
|
|
@ -247,12 +253,16 @@ std::string CArgumentParserImpl::getDescription(const std::string_view& header,
|
||||||
rolling += pad(maxArgWidth - lenUsed);
|
rolling += pad(maxArgWidth - lenUsed);
|
||||||
lenUsed = maxArgWidth;
|
lenUsed = maxArgWidth;
|
||||||
|
|
||||||
rolling += " -" + v.abbrev;
|
if (!v.abbrev.empty()) {
|
||||||
lenUsed += 2 + v.abbrev.size();
|
rolling += " -" + v.abbrev;
|
||||||
rolling += " ";
|
lenUsed += 2 + v.abbrev.size();
|
||||||
rolling += TYPE_STRS[v.argType];
|
|
||||||
lenUsed += std::string_view{TYPE_STRS[v.argType]}.length() + 1;
|
rolling += " ";
|
||||||
rolling += pad(maxArgWidth + maxShortWidth - lenUsed);
|
rolling += TYPE_STRS[v.argType];
|
||||||
|
lenUsed += std::string_view{TYPE_STRS[v.argType]}.length() + 1;
|
||||||
|
rolling += pad(maxArgWidth + maxShortWidth - lenUsed);
|
||||||
|
} else
|
||||||
|
rolling += pad(maxShortWidth);
|
||||||
lenUsed = maxArgWidth + maxShortWidth;
|
lenUsed = maxArgWidth + maxShortWidth;
|
||||||
|
|
||||||
rolling += " | ";
|
rolling += " | ";
|
||||||
|
|
@ -269,7 +279,7 @@ std::string CArgumentParserImpl::getDescription(const std::string_view& header,
|
||||||
|
|
||||||
for (size_t i = 1; i < ROWS.size(); ++i) {
|
for (size_t i = 1; i < ROWS.size(); ++i) {
|
||||||
lenUsed = LEN_START_DESC;
|
lenUsed = LEN_START_DESC;
|
||||||
rolling += "┣";
|
rolling += "┃";
|
||||||
rolling += pad(LEN_START_DESC);
|
rolling += pad(LEN_START_DESC);
|
||||||
rolling += ROWS[i];
|
rolling += ROWS[i];
|
||||||
lenUsed += ROWS[i].size();
|
lenUsed += ROWS[i].size();
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,14 @@ void CLoggerImpl::log(eLogLevel level, const std::string_view& msg, const std::s
|
||||||
logMsg += "]: ";
|
logMsg += "]: ";
|
||||||
logMsg += msg;
|
logMsg += msg;
|
||||||
|
|
||||||
if (m_stdoutEnabled)
|
if (m_stdoutEnabled) {
|
||||||
std::println("{}{}", m_colorEnabled ? logPrefixColor : logPrefix, logMsg);
|
try {
|
||||||
|
std::println("{}{}", m_colorEnabled ? logPrefixColor : logPrefix, logMsg);
|
||||||
|
std::fflush(stdout);
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
; // this could be e.g. stdout closed
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m_fileEnabled)
|
if (m_fileEnabled)
|
||||||
m_logOfs << logPrefix << logMsg << "\n";
|
m_logOfs << logPrefix << logMsg << "\n";
|
||||||
|
|
||||||
|
|
@ -179,3 +185,15 @@ void CLoggerConnection::log(eLogLevel level, const std::string_view& msg) {
|
||||||
|
|
||||||
m_impl->log(level, msg, m_name);
|
m_impl->log(level, msg, m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLogger* CLoggerConnection::getLogger() {
|
||||||
|
if (!m_impl)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLoggerConnection::redirect(CLogger& logger) {
|
||||||
|
m_impl = logger.m_impl;
|
||||||
|
m_logger = &logger;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ std::string CI18nEngine::localizeEntry(const std::string& locale, uint64_t key,
|
||||||
return std::string{rawStr};
|
return std::string{rawStr};
|
||||||
|
|
||||||
// build the new string. First, sort our entries
|
// build the new string. First, sort our entries
|
||||||
std::ranges::sort(rangesFound, [](const auto& a, const auto& b) { return a.begin - b.begin; });
|
std::ranges::sort(rangesFound, [](const auto& a, const auto& b) { return a.begin < b.begin; });
|
||||||
|
|
||||||
// calc the size
|
// calc the size
|
||||||
size_t stringLen = 0;
|
size_t stringLen = 0;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ template <typename VarType>
|
||||||
using CAnimatedVariable = CGenericAnimatedVariable<VarType, EmtpyContext>;
|
using CAnimatedVariable = CGenericAnimatedVariable<VarType, EmtpyContext>;
|
||||||
|
|
||||||
template <typename VarType>
|
template <typename VarType>
|
||||||
using PANIMVAR = SP<CAnimatedVariable<VarType>>;
|
using PANIMVAR = UP<CAnimatedVariable<VarType>>;
|
||||||
|
|
||||||
template <typename VarType>
|
template <typename VarType>
|
||||||
using PANIMVARREF = WP<CAnimatedVariable<VarType>>;
|
using PANIMVARREF = WP<CAnimatedVariable<VarType>>;
|
||||||
|
|
@ -47,8 +47,7 @@ CAnimationConfigTree animationTree;
|
||||||
class CMyAnimationManager : public CAnimationManager {
|
class CMyAnimationManager : public CAnimationManager {
|
||||||
public:
|
public:
|
||||||
void tick() {
|
void tick() {
|
||||||
for (size_t i = 0; i < m_vActiveAnimatedVariables.size(); i++) {
|
for (const auto& PAV : m_vActiveAnimatedVariables) {
|
||||||
const auto PAV = m_vActiveAnimatedVariables[i].lock();
|
|
||||||
if (!PAV || !PAV->ok() || !PAV->isBeingAnimated())
|
if (!PAV || !PAV->ok() || !PAV->isBeingAnimated())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -68,7 +67,7 @@ class CMyAnimationManager : public CAnimationManager {
|
||||||
if (!avInt)
|
if (!avInt)
|
||||||
std::cout << "Dynamic cast upcast failed\n";
|
std::cout << "Dynamic cast upcast failed\n";
|
||||||
|
|
||||||
const auto DELTA = avInt->goal() - avInt->value();
|
const auto DELTA = avInt->goal() - avInt->begun();
|
||||||
avInt->value() = avInt->begun() + (DELTA * POINTY);
|
avInt->value() = avInt->begun() + (DELTA * POINTY);
|
||||||
} break;
|
} break;
|
||||||
case eAVTypes::TEST: {
|
case eAVTypes::TEST: {
|
||||||
|
|
@ -93,11 +92,10 @@ class CMyAnimationManager : public CAnimationManager {
|
||||||
template <typename VarType>
|
template <typename VarType>
|
||||||
void createAnimation(const VarType& v, PANIMVAR<VarType>& av, const std::string& animationConfigName) {
|
void createAnimation(const VarType& v, PANIMVAR<VarType>& av, const std::string& animationConfigName) {
|
||||||
constexpr const eAVTypes EAVTYPE = std::is_same_v<VarType, int> ? eAVTypes::INT : eAVTypes::TEST;
|
constexpr const eAVTypes EAVTYPE = std::is_same_v<VarType, int> ? eAVTypes::INT : eAVTypes::TEST;
|
||||||
const auto PAV = makeShared<CGenericAnimatedVariable<VarType, EmtpyContext>>();
|
av = makeUnique<CGenericAnimatedVariable<VarType, EmtpyContext>>();
|
||||||
|
|
||||||
PAV->create(EAVTYPE, sc<CAnimationManager*>(this), PAV, v);
|
av->create2(EAVTYPE, sc<CAnimationManager*>(this), av, v);
|
||||||
PAV->setConfig(animationTree.getConfig(animationConfigName));
|
av->setConfig(animationTree.getConfig(animationConfigName));
|
||||||
av = std::move(PAV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void scheduleTick() {
|
virtual void scheduleTick() {
|
||||||
|
|
@ -298,7 +296,7 @@ TEST(Animation, animation) {
|
||||||
// test adding / removing vars during a tick
|
// test adding / removing vars during a tick
|
||||||
s.m_iA->resetAllCallbacks();
|
s.m_iA->resetAllCallbacks();
|
||||||
s.m_iA->setUpdateCallback([&vars](WP<CBaseAnimatedVariable> v) {
|
s.m_iA->setUpdateCallback([&vars](WP<CBaseAnimatedVariable> v) {
|
||||||
if (v.lock() != vars.back())
|
if (v.get() != vars.back().get())
|
||||||
vars.back()->warp();
|
vars.back()->warp();
|
||||||
});
|
});
|
||||||
s.m_iA->setCallbackOnEnd([&s, &vars](auto) {
|
s.m_iA->setCallbackOnEnd([&s, &vars](auto) {
|
||||||
|
|
@ -350,7 +348,7 @@ TEST(Animation, animation) {
|
||||||
*s.m_iA = 5;
|
*s.m_iA = 5;
|
||||||
s.m_iA->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> v) {
|
s.m_iA->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> v) {
|
||||||
endCallbackRan++;
|
endCallbackRan++;
|
||||||
const auto PAV = dc<CAnimatedVariable<int>*>(v.lock().get());
|
const auto PAV = dc<CAnimatedVariable<int>*>(v.get());
|
||||||
|
|
||||||
*PAV = 10;
|
*PAV = 10;
|
||||||
PAV->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> v) { endCallbackRan++; });
|
PAV->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> v) { endCallbackRan++; });
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@ using namespace Hyprutils;
|
||||||
constexpr const char* DESC_TEST = R"#(┏ My description
|
constexpr const char* DESC_TEST = R"#(┏ My description
|
||||||
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||||
┣ --hello -h | Says hello ┃
|
┣ --hello -h | Says hello ┃
|
||||||
┣ --hello2 -e | Says hello 2 ┃
|
┣ --hello2 | Says hello 2 ┃
|
||||||
┣ --value -v [float] | Sets a valueeeeeee ┃
|
┣ --value -v [float] | Sets a valueeeeeee ┃
|
||||||
┣ --longlonglonglongintopt -l [int] | Long long ┃
|
┣ --longlonglonglongintopt -l [int] | Long long ┃
|
||||||
┣ maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa┃
|
┃ maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa┃
|
||||||
┣ aaaaaaaaaaan maaan man maaan man maaan ┃
|
┃ aaaaaaaaaaan maaan man maaan man maaan ┃
|
||||||
┣ man maaan man ┃
|
┃ man maaan man ┃
|
||||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||||
)#";
|
)#";
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ TEST(CLI, ArgumentParser) {
|
||||||
CArgumentParser parser(argv);
|
CArgumentParser parser(argv);
|
||||||
|
|
||||||
EXPECT_TRUE(parser.registerBoolOption("hello", "h", "Says hello"));
|
EXPECT_TRUE(parser.registerBoolOption("hello", "h", "Says hello"));
|
||||||
EXPECT_TRUE(parser.registerBoolOption("hello2", "e", "Says hello 2"));
|
EXPECT_TRUE(parser.registerBoolOption("hello2", "", "Says hello 2"));
|
||||||
EXPECT_TRUE(parser.registerFloatOption("value", "v", "Sets a valueeeeeee"));
|
EXPECT_TRUE(parser.registerFloatOption("value", "v", "Sets a valueeeeeee"));
|
||||||
EXPECT_TRUE(parser.registerIntOption("longlonglonglongintopt", "l", "Long long maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan maaan man maaan man maaan man maaan man"));
|
EXPECT_TRUE(parser.registerIntOption("longlonglonglongintopt", "l", "Long long maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan maaan man maaan man maaan man maaan man"));
|
||||||
|
|
||||||
|
|
@ -49,6 +49,8 @@ TEST(CLI, ArgumentParser) {
|
||||||
EXPECT_TRUE(parser2.registerBoolOption("hello2", "e", "Says hello 2"));
|
EXPECT_TRUE(parser2.registerBoolOption("hello2", "e", "Says hello 2"));
|
||||||
EXPECT_TRUE(parser2.registerFloatOption("value", "v", "Sets a valueeeeeee"));
|
EXPECT_TRUE(parser2.registerFloatOption("value", "v", "Sets a valueeeeeee"));
|
||||||
EXPECT_TRUE(parser2.registerIntOption("longlonglonglongintopt", "l", "Long long maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan maaan man maaan man maaan man maaan man"));
|
EXPECT_TRUE(parser2.registerIntOption("longlonglonglongintopt", "l", "Long long maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan maaan man maaan man maaan man maaan man"));
|
||||||
|
EXPECT_TRUE(parser2.registerFloatOption("value2", "", "Sets a valueeeeeee 2"));
|
||||||
|
EXPECT_TRUE(!parser2.registerFloatOption("", "a", "Sets a valueeeeeee 2"));
|
||||||
|
|
||||||
auto result2 = parser2.parse();
|
auto result2 = parser2.parse();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,4 +75,6 @@ TEST(I18n, Engine) {
|
||||||
EXPECT_EQ(engine.localizeEntry("ts", 42069 /* invalid key */, {{"count", "1"}}), "");
|
EXPECT_EQ(engine.localizeEntry("ts", 42069 /* invalid key */, {{"count", "1"}}), "");
|
||||||
|
|
||||||
EXPECT_EQ(engine.localizeEntry("ts_TST", TXT_KEY_FALLBACK, {{"var1", "hi"}, {"var2", "!"}}), "Hello hi world !");
|
EXPECT_EQ(engine.localizeEntry("ts_TST", TXT_KEY_FALLBACK, {{"var1", "hi"}, {"var2", "!"}}), "Hello hi world !");
|
||||||
|
// Order shouldn't matter
|
||||||
|
EXPECT_EQ(engine.localizeEntry("ts_TST", TXT_KEY_FALLBACK, {{"var2", "!"}, {"var1", "hi"}}), "Hello hi world !");
|
||||||
}
|
}
|
||||||
|
|
@ -123,6 +123,119 @@ static void testAtomicImpl() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InterfaceA {
|
||||||
|
public:
|
||||||
|
virtual ~InterfaceA() = default;
|
||||||
|
int m_ifaceAInt = 69;
|
||||||
|
int m_ifaceAShit = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InterfaceB {
|
||||||
|
public:
|
||||||
|
virtual ~InterfaceB() = default;
|
||||||
|
int m_ifaceBInt = 2;
|
||||||
|
int m_ifaceBShit = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CChild : public InterfaceA, public InterfaceB {
|
||||||
|
public:
|
||||||
|
virtual ~CChild() = default;
|
||||||
|
int m_childInt = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CChildA : public InterfaceA {
|
||||||
|
public:
|
||||||
|
int m_childAInt = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void testHierarchy() {
|
||||||
|
// Same test for atomic and non-atomic
|
||||||
|
{
|
||||||
|
SP<CChildA> childA = makeShared<CChildA>();
|
||||||
|
auto ifaceA = SP<InterfaceA>(childA);
|
||||||
|
EXPECT_TRUE(ifaceA);
|
||||||
|
EXPECT_EQ(ifaceA->m_ifaceAInt, 69);
|
||||||
|
|
||||||
|
auto ifaceB = dynamicPointerCast<InterfaceA>(SP<CChildA>{});
|
||||||
|
EXPECT_TRUE(!ifaceB);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SP<CChild> child = makeShared<CChild>();
|
||||||
|
SP<InterfaceA> ifaceA = dynamicPointerCast<InterfaceA>(child);
|
||||||
|
SP<InterfaceB> ifaceB = dynamicPointerCast<InterfaceB>(child);
|
||||||
|
EXPECT_TRUE(ifaceA);
|
||||||
|
EXPECT_TRUE(ifaceB);
|
||||||
|
|
||||||
|
EXPECT_EQ(ifaceA->m_ifaceAInt, 69);
|
||||||
|
EXPECT_EQ(ifaceB->m_ifaceBInt, 2);
|
||||||
|
|
||||||
|
WP<InterfaceA> ifaceAWeak = ifaceA;
|
||||||
|
|
||||||
|
child.reset();
|
||||||
|
EXPECT_TRUE(ifaceAWeak);
|
||||||
|
EXPECT_TRUE(ifaceA);
|
||||||
|
EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69);
|
||||||
|
EXPECT_EQ(ifaceA->m_ifaceAInt, 69);
|
||||||
|
ifaceA.reset();
|
||||||
|
EXPECT_TRUE(ifaceAWeak);
|
||||||
|
EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69);
|
||||||
|
EXPECT_TRUE(ifaceB);
|
||||||
|
EXPECT_EQ(ifaceB->m_ifaceBInt, 2);
|
||||||
|
ifaceB.reset();
|
||||||
|
EXPECT_TRUE(!ifaceAWeak);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
{
|
||||||
|
ASP<CChildA> childA = makeAtomicShared<CChildA>();
|
||||||
|
auto ifaceA = ASP<InterfaceA>(childA);
|
||||||
|
EXPECT_TRUE(ifaceA);
|
||||||
|
EXPECT_EQ(ifaceA->m_ifaceAInt, 69);
|
||||||
|
|
||||||
|
auto ifaceB = dynamicPointerCast<InterfaceA>(ASP<CChildA>{});
|
||||||
|
EXPECT_TRUE(!ifaceB);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ASP<CChild> child = makeAtomicShared<CChild>();
|
||||||
|
ASP<InterfaceA> ifaceA = dynamicPointerCast<InterfaceA>(child);
|
||||||
|
ASP<InterfaceB> ifaceB = dynamicPointerCast<InterfaceB>(child);
|
||||||
|
EXPECT_TRUE(ifaceA);
|
||||||
|
EXPECT_TRUE(ifaceB);
|
||||||
|
|
||||||
|
EXPECT_EQ(ifaceA->m_ifaceAInt, 69);
|
||||||
|
EXPECT_EQ(ifaceB->m_ifaceBInt, 2);
|
||||||
|
|
||||||
|
AWP<InterfaceA> ifaceAWeak = ifaceA;
|
||||||
|
AWP<InterfaceB> ifaceBWeak = dynamicPointerCast<InterfaceB>(ifaceA);
|
||||||
|
|
||||||
|
child.reset();
|
||||||
|
EXPECT_TRUE(ifaceAWeak);
|
||||||
|
EXPECT_TRUE(ifaceBWeak);
|
||||||
|
EXPECT_TRUE(ifaceA);
|
||||||
|
EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69);
|
||||||
|
EXPECT_EQ(ifaceA->m_ifaceAInt, 69);
|
||||||
|
EXPECT_EQ(ifaceBWeak->m_ifaceBInt, 2);
|
||||||
|
ifaceA.reset();
|
||||||
|
EXPECT_TRUE(ifaceAWeak);
|
||||||
|
EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69);
|
||||||
|
EXPECT_TRUE(ifaceB);
|
||||||
|
EXPECT_EQ(ifaceB->m_ifaceBInt, 2);
|
||||||
|
EXPECT_EQ(ifaceBWeak->m_ifaceBInt, 2);
|
||||||
|
ifaceB.reset();
|
||||||
|
EXPECT_TRUE(!ifaceAWeak);
|
||||||
|
EXPECT_TRUE(!ifaceBWeak);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test for leaks
|
||||||
|
for (size_t i = 0; i < 10000; ++i) {
|
||||||
|
auto child = makeAtomicShared<CChild>();
|
||||||
|
auto child2 = makeShared<CChild>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Memory, memory) {
|
TEST(Memory, memory) {
|
||||||
SP<int> intPtr = makeShared<int>(10);
|
SP<int> intPtr = makeShared<int>(10);
|
||||||
SP<int> intPtr2 = makeShared<int>(-1337);
|
SP<int> intPtr2 = makeShared<int>(-1337);
|
||||||
|
|
@ -176,4 +289,6 @@ TEST(Memory, memory) {
|
||||||
EXPECT_EQ(*intPtr2, 10);
|
EXPECT_EQ(*intPtr2, 10);
|
||||||
|
|
||||||
testAtomicImpl();
|
testAtomicImpl();
|
||||||
|
|
||||||
|
testHierarchy();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue