diff --git a/libraries/libstratosphere/include/stratosphere/sf.hpp b/libraries/libstratosphere/include/stratosphere/sf.hpp index 6849bfdcb..e073e3395 100644 --- a/libraries/libstratosphere/include/stratosphere/sf.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf.hpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_native_handle.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_native_handle.hpp new file mode 100644 index 000000000..bc5a8f6aa --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_native_handle.hpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::sf { + + class NativeHandle { + NON_COPYABLE(NativeHandle); + private: + os::NativeHandle m_handle; + bool m_managed; + public: + constexpr NativeHandle() : m_handle(os::InvalidNativeHandle), m_managed(false) { /* ... */ } + + constexpr NativeHandle(os::NativeHandle handle, bool managed) : m_handle(handle), m_managed(managed) { /* ... */ } + + constexpr NativeHandle(NativeHandle &&rhs) : m_handle(rhs.m_handle), m_managed(rhs.m_managed) { + rhs.m_managed = false; + rhs.m_handle = os::InvalidNativeHandle; + } + + constexpr NativeHandle &operator=(NativeHandle &&rhs) { + NativeHandle(std::move(rhs)).swap(*this); + return *this; + } + + constexpr ~NativeHandle() { + if (m_managed) { + os::CloseNativeHandle(m_handle); + } + } + + constexpr void Detach() { + m_managed = false; + m_handle = os::InvalidNativeHandle; + } + + constexpr void Swap(NativeHandle &rhs) { + std::swap(m_handle, rhs.m_handle); + std::swap(m_managed, rhs.m_managed); + } + + constexpr ALWAYS_INLINE void swap(NativeHandle &rhs) { + return Swap(rhs); + } + + constexpr NativeHandle GetShared() const { + return NativeHandle(m_handle, false); + } + + constexpr os::NativeHandle GetOsHandle() const { + return m_handle; + } + + constexpr bool IsManaged() const { + return m_managed; + } + + constexpr void Reset() { + NativeHandle().swap(*this); + } + }; + + ALWAYS_INLINE void swap(NativeHandle &lhs, NativeHandle &rhs) { + lhs.swap(rhs); + } + + template<> + class Out { + private: + NativeHandle *m_ptr; + public: + Out(NativeHandle *p) : m_ptr(p) { /* ... */ } + + void SetValue(NativeHandle v) const { + *m_ptr = std::move(v); + } + + NativeHandle &operator*() const { + return *m_ptr; + } + }; + +} \ No newline at end of file