1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-24 01:54:22 +00:00

Obj-C++: Added obc_msgSendSuper_stret overloads for ObjCMsgSendSuper() and refactored the superclass messaging a bit

This commit is contained in:
ed 2020-07-10 16:46:29 +01:00
parent 754ec66b42
commit c8a416f476
5 changed files with 54 additions and 61 deletions

View file

@ -143,14 +143,12 @@ public:
virtual NSDictionary<NSString*, id>* getFullState()
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
return ObjCMsgSendSuper<NSDictionary<NSString*, id>*> (&s, @selector (fullState));
return ObjCMsgSendSuper<AUAudioUnit, NSDictionary<NSString*, id>*> (getAudioUnit(), @selector (fullState));
}
virtual void setFullState (NSDictionary<NSString*, id>* state)
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
ObjCMsgSendSuper<void, NSDictionary<NSString*, id>*> (&s, @selector (setFullState:), state);
ObjCMsgSendSuper<AUAudioUnit, void> (getAudioUnit(), @selector (setFullState:), state);
}
virtual AUParameterTree* getParameterTree() = 0;
@ -179,14 +177,12 @@ public:
virtual bool getShouldBypassEffect()
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
return (ObjCMsgSendSuper<BOOL> (&s, @selector (shouldBypassEffect)) == YES);
return (ObjCMsgSendSuper<AUAudioUnit, BOOL> (getAudioUnit(), @selector (shouldBypassEffect)) == YES);
}
virtual void setShouldBypassEffect (bool shouldBypass)
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
ObjCMsgSendSuper<void, BOOL> (&s, @selector (setShouldBypassEffect:), shouldBypass ? YES : NO);
ObjCMsgSendSuper<AUAudioUnit, void> (getAudioUnit(), @selector (setShouldBypassEffect:), shouldBypass ? YES : NO);
}
//==============================================================================
@ -195,14 +191,12 @@ public:
virtual bool allocateRenderResourcesAndReturnError (NSError **outError)
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
return (ObjCMsgSendSuper<BOOL, NSError**> (&s, @selector (allocateRenderResourcesAndReturnError:), outError) == YES);
return (ObjCMsgSendSuper<AUAudioUnit, BOOL, NSError**> (getAudioUnit(), @selector (allocateRenderResourcesAndReturnError:), outError) == YES);
}
virtual void deallocateRenderResources()
{
objc_super s = { getAudioUnit(), [AUAudioUnit class] };
ObjCMsgSendSuper<void> (&s, @selector (deallocateRenderResources));
ObjCMsgSendSuper<AUAudioUnit, void> (getAudioUnit(), @selector (deallocateRenderResources));
}
//==============================================================================
@ -294,9 +288,8 @@ private:
{
AUAudioUnit* self = _self;
objc_super s = { self, [AUAudioUnit class] };
self = ObjCMsgSendSuper<AUAudioUnit*, AudioComponentDescription,
AudioComponentInstantiationOptions, NSError**> (&s, @selector(initWithComponentDescription:options:error:), descr, options, error);
self = ObjCMsgSendSuper<AUAudioUnit, AUAudioUnit*, AudioComponentDescription,
AudioComponentInstantiationOptions, NSError**> (self, @selector (initWithComponentDescription:options:error:), descr, options, error);
JuceAudioUnitv3Base* juceAU = JuceAudioUnitv3Base::create (self, descr, options, error);
@ -308,9 +301,8 @@ private:
{
AUAudioUnit* self = _self;
objc_super s = { self, [AUAudioUnit class] };
self = ObjCMsgSendSuper<AUAudioUnit*, AudioComponentDescription,
AudioComponentInstantiationOptions, NSError**> (&s, @selector(initWithComponentDescription:options:error:), descr, options, error);
self = ObjCMsgSendSuper<AUAudioUnit, AUAudioUnit*, AudioComponentDescription,
AudioComponentInstantiationOptions, NSError**> (self, @selector(initWithComponentDescription:options:error:), descr, options, error);
setThis (self, juceAU);

View file

@ -80,7 +80,6 @@ private:
static void dealloc (id self, SEL)
{
[getController (self) release];
sendSuperclassMessage<void> (self, @selector (dealloc));
}

View file

@ -192,21 +192,33 @@ NSRect makeNSRect (const RectangleType& r) noexcept
static_cast<CGFloat> (r.getHeight()));
}
#endif
#if JUCE_MAC || JUCE_IOS
// This is necessary as on iOS/ARM builds, some arguments may be passed on registers
// depending on the argument type. The re-cast objc_msgSendSuper to a function
// take the same arguments as the target method.
template <typename ReturnValue, typename... Params>
ReturnValue ObjCMsgSendSuper (struct objc_super* s, SEL sel, Params... params)
{
using SuperFn = ReturnValue (*)(struct objc_super*, SEL, Params...);
SuperFn fn = reinterpret_cast<SuperFn> (objc_msgSendSuper);
return fn (s, sel, params...);
}
#if JUCE_INTEL
template <typename T>
struct NeedsStret { static constexpr auto value = sizeof (T) > 16; };
template<>
struct NeedsStret<void> { static constexpr auto value = false; };
template <typename T, bool b = NeedsStret<T>::value>
struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper_stret; };
template <typename T>
struct MetaSuperFn<T, false> { static constexpr auto value = objc_msgSendSuper; };
#else
template <typename>
struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper; };
#endif
template <typename SuperType, typename ReturnType, typename... Params>
static ReturnType ObjCMsgSendSuper (id self, SEL sel, Params... params)
{
using SuperFn = ReturnType (*) (struct objc_super*, SEL, Params...);
const auto fn = reinterpret_cast<SuperFn> (MetaSuperFn<ReturnType>::value);
objc_super s = { self, [SuperType class] };
return fn (&s, sel, params...);
}
//==============================================================================
struct NSObjectDeleter
{
@ -278,14 +290,11 @@ struct ObjCClass
jassert (b); ignoreUnused (b);
}
#if JUCE_MAC || JUCE_IOS
template <typename Result>
static Result sendSuperclassMessage (id self, SEL selector)
template <typename ReturnType, typename... Params>
static ReturnType sendSuperclassMessage (id self, SEL sel, Params... params)
{
objc_super s = { self, [SuperclassType class] };
return ObjCMsgSendSuper<Result> (&s, selector);
return ObjCMsgSendSuper<SuperclassType, ReturnType, Params...> (self, sel, params...);
}
#endif
template <typename Type>
static Type getIvar (id self, const char* name)
@ -322,18 +331,14 @@ struct ObjCLifetimeManagedClass : public ObjCClass<NSObject>
addMethod (@selector (dealloc), dealloc, "v@:");
registerClass();
}
static id initWithJuceObject (id _self, SEL, JuceClass* obj)
{
NSObject* self = _self;
objc_super s = { self, [NSObject class] };
self = ObjCMsgSendSuper<NSObject*> (&s, @selector(init));
NSObject* self = sendSuperclassMessage<NSObject*> (_self, @selector (init));
object_setInstanceVariable (self, "cppObject", obj);
return self;
}
@ -345,11 +350,9 @@ struct ObjCLifetimeManagedClass : public ObjCClass<NSObject>
object_setInstanceVariable (_self, "cppObject", nullptr);
}
objc_super s = { _self, [NSObject class] };
ObjCMsgSendSuper<void> (&s, @selector(dealloc));
sendSuperclassMessage<void> (_self, @selector (dealloc));
}
static ObjCLifetimeManagedClass objCLifetimeManagedClass;
};

View file

@ -1771,10 +1771,7 @@ private:
owner->stringBeingComposed.clear();
if (! (owner->textWasInserted || owner->redirectKeyDown (ev)))
{
objc_super s = { self, [NSView class] };
ObjCMsgSendSuper<void> (&s, @selector (keyDown:), ev);
}
sendSuperclassMessage<void> (self, @selector (keyDown:), ev);
}
}
@ -1782,11 +1779,8 @@ private:
{
auto* owner = getOwner (self);
if (owner == nullptr || ! owner->redirectKeyUp (ev))
{
objc_super s = { self, [NSView class] };
ObjCMsgSendSuper<void> (&s, @selector (keyUp:), ev);
}
if (! owner->redirectKeyUp (ev))
sendSuperclassMessage<void> (self, @selector (keyUp:), ev);
}
//==============================================================================
@ -2058,7 +2052,7 @@ private:
return owner == nullptr || owner->windowShouldClose();
}
static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen*)
static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen* screen)
{
if (auto* owner = getOwner (self))
frameRect = owner->constrainRect (frameRect);
@ -2105,10 +2099,10 @@ private:
{
if (auto* owner = getOwner (self))
{
owner->isZooming = true;
objc_super s = { self, [NSWindow class] };
ObjCMsgSendSuper<void> (&s, @selector (zoom:), sender);
owner->isZooming = false;
{
const ScopedValueSetter<bool> svs (owner->isZooming, true);
sendSuperclassMessage<void> (self, @selector (zoom:), sender);
}
owner->redirectMovedOrResized();
}

View file

@ -276,11 +276,17 @@ struct WebViewKeyEquivalentResponder : public ObjCClass<WebView>
{
WebViewKeyEquivalentResponder() : ObjCClass<WebView> ("WebViewKeyEquivalentResponder_")
{
addIvar<WebViewKeyEquivalentResponder*> ("owner");
addMethod (@selector (performKeyEquivalent:), performKeyEquivalent, @encode (BOOL), "@:@");
registerClass();
}
private:
static WebViewKeyEquivalentResponder* getOwner (id self)
{
return getIvar<WebViewKeyEquivalentResponder*> (self, "owner");
}
static BOOL performKeyEquivalent (id self, SEL selector, NSEvent* event)
{
NSResponder* first = [[self window] firstResponder];
@ -293,8 +299,7 @@ private:
if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) return [NSApp sendAction:@selector(selectAll:) to:first from:self];
}
objc_super s = { self, [WebView class] };
return ObjCMsgSendSuper<BOOL> (&s, selector, event);
return sendSuperclassMessage<BOOL> (self, selector, event);
}
};