mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-08 03:51:39 +12:00
metal: initial support
This commit is contained in:
parent
29d9ed7224
commit
f0547d1a71
167 changed files with 28839 additions and 1271 deletions
302
third_party/metal-cpp/Foundation/NSObject.hpp
vendored
Normal file
302
third_party/metal-cpp/Foundation/NSObject.hpp
vendored
Normal file
|
@ -0,0 +1,302 @@
|
|||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Foundation/NSObject.hpp
|
||||
//
|
||||
// Copyright 2020-2023 Apple Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "NSDefines.hpp"
|
||||
#include "NSPrivate.hpp"
|
||||
#include "NSTypes.hpp"
|
||||
|
||||
#include <objc/message.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace NS
|
||||
{
|
||||
template <class _Class, class _Base = class Object>
|
||||
class _NS_EXPORT Referencing : public _Base
|
||||
{
|
||||
public:
|
||||
_Class* retain();
|
||||
void release();
|
||||
|
||||
_Class* autorelease();
|
||||
|
||||
UInteger retainCount() const;
|
||||
};
|
||||
|
||||
template <class _Class, class _Base = class Object>
|
||||
class Copying : public Referencing<_Class, _Base>
|
||||
{
|
||||
public:
|
||||
_Class* copy() const;
|
||||
};
|
||||
|
||||
template <class _Class, class _Base = class Object>
|
||||
class SecureCoding : public Referencing<_Class, _Base>
|
||||
{
|
||||
};
|
||||
|
||||
class Object : public Referencing<Object, objc_object>
|
||||
{
|
||||
public:
|
||||
UInteger hash() const;
|
||||
bool isEqual(const Object* pObject) const;
|
||||
|
||||
class String* description() const;
|
||||
class String* debugDescription() const;
|
||||
|
||||
protected:
|
||||
friend class Referencing<Object, objc_object>;
|
||||
|
||||
template <class _Class>
|
||||
static _Class* alloc(const char* pClassName);
|
||||
template <class _Class>
|
||||
static _Class* alloc(const void* pClass);
|
||||
template <class _Class>
|
||||
_Class* init();
|
||||
|
||||
template <class _Dst>
|
||||
static _Dst bridgingCast(const void* pObj);
|
||||
static class MethodSignature* methodSignatureForSelector(const void* pObj, SEL selector);
|
||||
static bool respondsToSelector(const void* pObj, SEL selector);
|
||||
template <typename _Type>
|
||||
static constexpr bool doesRequireMsgSendStret();
|
||||
template <typename _Ret, typename... _Args>
|
||||
static _Ret sendMessage(const void* pObj, SEL selector, _Args... args);
|
||||
template <typename _Ret, typename... _Args>
|
||||
static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args);
|
||||
|
||||
private:
|
||||
Object() = delete;
|
||||
Object(const Object&) = delete;
|
||||
~Object() = delete;
|
||||
|
||||
Object& operator=(const Object&) = delete;
|
||||
};
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class, class _Base /* = Object */>
|
||||
_NS_INLINE _Class* NS::Referencing<_Class, _Base>::retain()
|
||||
{
|
||||
return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(retain));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class, class _Base /* = Object */>
|
||||
_NS_INLINE void NS::Referencing<_Class, _Base>::release()
|
||||
{
|
||||
Object::sendMessage<void>(this, _NS_PRIVATE_SEL(release));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class, class _Base /* = Object */>
|
||||
_NS_INLINE _Class* NS::Referencing<_Class, _Base>::autorelease()
|
||||
{
|
||||
return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(autorelease));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class, class _Base /* = Object */>
|
||||
_NS_INLINE NS::UInteger NS::Referencing<_Class, _Base>::retainCount() const
|
||||
{
|
||||
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(retainCount));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class, class _Base /* = Object */>
|
||||
_NS_INLINE _Class* NS::Copying<_Class, _Base>::copy() const
|
||||
{
|
||||
return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(copy));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Dst>
|
||||
_NS_INLINE _Dst NS::Object::bridgingCast(const void* pObj)
|
||||
{
|
||||
#ifdef __OBJC__
|
||||
return (__bridge _Dst)pObj;
|
||||
#else
|
||||
return (_Dst)pObj;
|
||||
#endif // __OBJC__
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename _Type>
|
||||
_NS_INLINE constexpr bool NS::Object::doesRequireMsgSendStret()
|
||||
{
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
constexpr size_t kStructLimit = (sizeof(std::uintptr_t) << 1);
|
||||
|
||||
return sizeof(_Type) > kStructLimit;
|
||||
#elif defined(__arm64__)
|
||||
return false;
|
||||
#elif defined(__arm__)
|
||||
constexpr size_t kStructLimit = sizeof(std::uintptr_t);
|
||||
|
||||
return std::is_class(_Type) && (sizeof(_Type) > kStructLimit);
|
||||
#else
|
||||
#error "Unsupported architecture!"
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
_NS_INLINE constexpr bool NS::Object::doesRequireMsgSendStret<void>()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename _Ret, typename... _Args>
|
||||
_NS_INLINE _Ret NS::Object::sendMessage(const void* pObj, SEL selector, _Args... args)
|
||||
{
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
if constexpr (std::is_floating_point<_Ret>())
|
||||
{
|
||||
using SendMessageProcFpret = _Ret (*)(const void*, SEL, _Args...);
|
||||
|
||||
const SendMessageProcFpret pProc = reinterpret_cast<SendMessageProcFpret>(&objc_msgSend_fpret);
|
||||
|
||||
return (*pProc)(pObj, selector, args...);
|
||||
}
|
||||
else
|
||||
#endif // ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||
#if !defined(__arm64__)
|
||||
if constexpr (doesRequireMsgSendStret<_Ret>())
|
||||
{
|
||||
using SendMessageProcStret = void (*)(_Ret*, const void*, SEL, _Args...);
|
||||
|
||||
const SendMessageProcStret pProc = reinterpret_cast<SendMessageProcStret>(&objc_msgSend_stret);
|
||||
_Ret ret;
|
||||
|
||||
(*pProc)(&ret, pObj, selector, args...);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
#endif // !defined( __arm64__ )
|
||||
{
|
||||
using SendMessageProc = _Ret (*)(const void*, SEL, _Args...);
|
||||
|
||||
const SendMessageProc pProc = reinterpret_cast<SendMessageProc>(&objc_msgSend);
|
||||
|
||||
return (*pProc)(pObj, selector, args...);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
_NS_INLINE NS::MethodSignature* NS::Object::methodSignatureForSelector(const void* pObj, SEL selector)
|
||||
{
|
||||
return sendMessage<MethodSignature*>(pObj, _NS_PRIVATE_SEL(methodSignatureForSelector_), selector);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
_NS_INLINE bool NS::Object::respondsToSelector(const void* pObj, SEL selector)
|
||||
{
|
||||
return sendMessage<bool>(pObj, _NS_PRIVATE_SEL(respondsToSelector_), selector);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename _Ret, typename... _Args>
|
||||
_NS_INLINE _Ret NS::Object::sendMessageSafe(const void* pObj, SEL selector, _Args... args)
|
||||
{
|
||||
if ((respondsToSelector(pObj, selector)) || (nullptr != methodSignatureForSelector(pObj, selector)))
|
||||
{
|
||||
return sendMessage<_Ret>(pObj, selector, args...);
|
||||
}
|
||||
|
||||
if constexpr (!std::is_void<_Ret>::value)
|
||||
{
|
||||
return _Ret(0);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class>
|
||||
_NS_INLINE _Class* NS::Object::alloc(const char* pClassName)
|
||||
{
|
||||
return sendMessage<_Class*>(objc_lookUpClass(pClassName), _NS_PRIVATE_SEL(alloc));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class>
|
||||
_NS_INLINE _Class* NS::Object::alloc(const void* pClass)
|
||||
{
|
||||
return sendMessage<_Class*>(pClass, _NS_PRIVATE_SEL(alloc));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class _Class>
|
||||
_NS_INLINE _Class* NS::Object::init()
|
||||
{
|
||||
return sendMessage<_Class*>(this, _NS_PRIVATE_SEL(init));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
_NS_INLINE NS::UInteger NS::Object::hash() const
|
||||
{
|
||||
return sendMessage<UInteger>(this, _NS_PRIVATE_SEL(hash));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
_NS_INLINE bool NS::Object::isEqual(const Object* pObject) const
|
||||
{
|
||||
return sendMessage<bool>(this, _NS_PRIVATE_SEL(isEqual_), pObject);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
_NS_INLINE NS::String* NS::Object::description() const
|
||||
{
|
||||
return sendMessage<String*>(this, _NS_PRIVATE_SEL(description));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
_NS_INLINE NS::String* NS::Object::debugDescription() const
|
||||
{
|
||||
return sendMessageSafe<String*>(this, _NS_PRIVATE_SEL(debugDescription));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
Loading…
Add table
Add a link
Reference in a new issue