Cache frequently used selectors instead of calling sel_registerName all the time in cocoa backend

This commit is contained in:
UnknownShadow200 2019-10-03 07:50:01 +10:00
parent ca0698c083
commit 2cf32a7c31

View File

@ -3628,6 +3628,40 @@ void GLContext_SetFpsLimit(bool vsync, float minFrameMs) {
static id appHandle, winHandle, viewHandle; static id appHandle, winHandle, viewHandle;
extern void* NSDefaultRunLoopMode; extern void* NSDefaultRunLoopMode;
static SEL selFrame, selDeltaX, selDeltaY;
static SEL selNextEvent, selType, selSendEvent;
static SEL selButton, selKeycode, selModifiers;
static SEL selCharacters, selUtf8String, selMouseLoc;
static SEL selCurrentContext, selGraphicsPort;
statoc SEL selSetNeedsDisplay, selDisplayInRect;
static SEL selUpdate, selFlushBuffer;
static void RegisterSelectors(void) {
selFrame = sel_registerName("frame");
selDeltaX = sel_registerName("deltaX");
selDeltaY = sel_registerName("deltaY");
selNextEvent = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:");
selType = sel_registerName("type");
selSendEvent = sel_registerName("sendEvent:");
selButton = sel_registerName("buttonNumber");
selKecode = sel_registerName("keyCode");
selModifiers = sel_registerName("modifierFlags");
selCharacters = sel_registerName("charactersIgnoringModifiers");
selUtf8String = sel_registerName("UTF8String");
selMouseLoc = sel_registerName("mouseLocation");
selCurrentContext = sel_registerName("currentContext");
selGraphicsPort = sel_registerName("graphicsPort");
selSetNeedsDisplay = sel_registerName("setNeedsDisplayInRect:");
selDisplayIfNeeded = sel_registerName("displayIfNeeded");
selUpdate = sel_registerName("update")
selFlushBuffer = sel_registerName("flushBuffer");
}
static CC_INLINE CGFloat Send_CGFloat(id receiver, SEL sel) { static CC_INLINE CGFloat Send_CGFloat(id receiver, SEL sel) {
/* Sometimes we have to use fpret and sometimes we don't. See this for more details: */ /* Sometimes we have to use fpret and sometimes we don't. See this for more details: */
/* http://www.sealiesoftware.com/blog/archive/2008/11/16/objc_explain_objc_msgSend_fpret.html */ /* http://www.sealiesoftware.com/blog/archive/2008/11/16/objc_explain_objc_msgSend_fpret.html */
@ -3649,8 +3683,8 @@ static void Window_RefreshBounds(void) {
CGRect win, view; CGRect win, view;
int viewY; int viewY;
win = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(winHandle, sel_registerName("frame")); win = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(winHandle, selFrame);
view = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(viewHandle, sel_registerName("frame")); view = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(viewHandle, selFrame);
/* For cocoa, the 0,0 origin is the bottom left corner of windows/views/screen. */ /* For cocoa, the 0,0 origin is the bottom left corner of windows/views/screen. */
/* To get window's real Y screen position, first need to find Y of top. (win.y + win.height) */ /* To get window's real Y screen position, first need to find Y of top. (win.y + win.height) */
@ -3724,7 +3758,7 @@ static void Window_MakeView(void) {
Class c; Class c;
view = objc_msgSend(winHandle, sel_registerName("contentView")); view = objc_msgSend(winHandle, sel_registerName("contentView"));
rect = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(view, sel_registerName("frame")); rect = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(view, selFrame);
c = objc_allocateClassPair(objc_getClass("NSView"), "ClassiCube_View", 0); c = objc_allocateClassPair(objc_getClass("NSView"), "ClassiCube_View", 0);
// TODO: test rect is actually correct in View_DrawRect on both 32 and 64 bit // TODO: test rect is actually correct in View_DrawRect on both 32 and 64 bit
@ -3744,6 +3778,7 @@ void Window_Init(void) {
appHandle = objc_msgSend((id)objc_getClass("NSApplication"), sel_registerName("sharedApplication")); appHandle = objc_msgSend((id)objc_getClass("NSApplication"), sel_registerName("sharedApplication"));
objc_msgSend(appHandle, sel_registerName("activateIgnoringOtherApps:"), true); objc_msgSend(appHandle, sel_registerName("activateIgnoringOtherApps:"), true);
Window_CommonInit(); Window_CommonInit();
RegisterSelectors();
} }
#define NSTitledWindowMask (1 << 0) #define NSTitledWindowMask (1 << 0)
@ -3809,7 +3844,7 @@ void Window_ExitFullscreen(void) {
void Window_SetSize(int width, int height) { void Window_SetSize(int width, int height) {
/* Can't use setContentSize:, because that resizes from the bottom left corner. */ /* Can't use setContentSize:, because that resizes from the bottom left corner. */
CGRect rect = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(winHandle, sel_registerName("frame")); CGRect rect = ((CGRect(*)(id, SEL))(void *)objc_msgSend_stret)(winHandle, selFrame);
rect.origin.y += Window_Height - height; rect.origin.y += Window_Height - height;
rect.size.width += width - Window_Width; rect.size.width += width - Window_Width;
@ -3835,8 +3870,8 @@ static void Window_ProcessKeyChars(id ev) {
id chars; id chars;
int i, len; int i, len;
chars = objc_msgSend(ev, sel_registerName("charactersIgnoringModifiers")); chars = objc_msgSend(ev, selCharacters);
src = objc_msgSend(chars, sel_registerName("UTF8String")); src = objc_msgSend(chars, selUtf8String);
len = String_CalcLen(src, UInt16_MaxValue); len = String_CalcLen(src, UInt16_MaxValue);
String_InitArray(str, buffer); String_InitArray(str, buffer);
@ -3847,7 +3882,7 @@ static void Window_ProcessKeyChars(id ev) {
} }
static bool GetMouseCoords(int* x, int* y) { static bool GetMouseCoords(int* x, int* y) {
CGPoint loc = Send_CGPoint((id)objc_getClass("NSEvent"), sel_registerName("mouseLocation")); CGPoint loc = Send_CGPoint((id)objc_getClass("NSEvent"), selMouseLoc);
*x = (int)loc.x - windowX; *x = (int)loc.x - windowX;
*y = (Display_Bounds.Height - (int)loc.y) - windowY; *y = (Display_Bounds.Height - (int)loc.y) - windowY;
// TODO: this seems to be off by 1 // TODO: this seems to be off by 1
@ -3858,43 +3893,41 @@ void Window_ProcessEvents(void) {
id ev; id ev;
int key, type, steps, x, y; int key, type, steps, x, y;
CGFloat dx, dy; CGFloat dx, dy;
float aaa;
for (;;) { for (;;) {
ev = objc_msgSend(appHandle, sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:"), 0xFFFFFFFFU, NULL, NSDefaultRunLoopMode, true); ev = objc_msgSend(appHandle, selNextEvent, 0xFFFFFFFFU, NULL, NSDefaultRunLoopMode, true);
if (!ev) break; if (!ev) break;
type = (int)objc_msgSend(ev, sel_registerName("type")); type = (int)objc_msgSend(ev, selType);
// TODO: Only raise these events inside the window
switch (type) { switch (type) {
case 1: /* NSLeftMouseDown */ case 1: /* NSLeftMouseDown */
case 3: /* NSRightMouseDown */ case 3: /* NSRightMouseDown */
case 25: /* NSOtherMouseDown */ case 25: /* NSOtherMouseDown */
key = Window_MapMouse((int)objc_msgSend(ev, sel_registerName("buttonNumber"))); key = Window_MapMouse((int)objc_msgSend(ev, selButton));
if (GetMouseCoords(&x, &y) && key) Input_SetPressed(key, true); if (GetMouseCoords(&x, &y) && key) Input_SetPressed(key, true);
break; break;
case 2: /* NSLeftMouseUp */ case 2: /* NSLeftMouseUp */
case 4: /* NSRightMouseUp */ case 4: /* NSRightMouseUp */
case 26: /* NSOtherMouseUp */ case 26: /* NSOtherMouseUp */
key = Window_MapMouse((int)objc_msgSend(ev, sel_registerName("buttonNumber"))); key = Window_MapMouse((int)objc_msgSend(ev, selButton));
if (GetMouseCoords(&x, &y) && key) Input_SetPressed(key, false); if (GetMouseCoords(&x, &y) && key) Input_SetPressed(key, false);
break; break;
case 10: /* NSKeyDown */ case 10: /* NSKeyDown */
key = Window_MapKey((int)objc_msgSend(ev, sel_registerName("keyCode"))); key = Window_MapKey((int)objc_msgSend(ev, selKeycode));
if (key) Input_SetPressed(key, true); if (key) Input_SetPressed(key, true);
// TODO: Test works properly with other languages // TODO: Test works properly with other languages
Window_ProcessKeyChars(ev); Window_ProcessKeyChars(ev);
break; break;
case 11: /* NSKeyUp */ case 11: /* NSKeyUp */
key = Window_MapKey((int)objc_msgSend(ev, sel_registerName("keyCode"))); key = Window_MapKey((int)objc_msgSend(ev, selKeycode));
if (key) Input_SetPressed(key, false); if (key) Input_SetPressed(key, false);
break; break;
case 12: /* NSFlagsChanged */ case 12: /* NSFlagsChanged */
key = (int)objc_msgSend(ev, sel_registerName("modifierFlags")); key = (int)objc_msgSend(ev, selModifiers);
/* TODO: Figure out how to only get modifiers that changed */ /* TODO: Figure out how to only get modifiers that changed */
Input_SetPressed(KEY_LCTRL, (key & 0x000001) != 0); Input_SetPressed(KEY_LCTRL, (key & 0x000001) != 0);
Input_SetPressed(KEY_LSHIFT, (key & 0x000002) != 0); Input_SetPressed(KEY_LSHIFT, (key & 0x000002) != 0);
@ -3908,7 +3941,7 @@ void Window_ProcessEvents(void) {
break; break;
case 22: /* NSScrollWheel */ case 22: /* NSScrollWheel */
dy = Send_CGFloat(ev, sel_registerName("deltaY")); dy = Send_CGFloat(ev, selDeltaY);
/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=220175 */ /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=220175 */
/* delta is in 'line height' units, but I don't know how to map that to actual units. */ /* delta is in 'line height' units, but I don't know how to map that to actual units. */
/* All I know is that scrolling by '1 wheel notch' produces a delta of around 0.1, and that */ /* All I know is that scrolling by '1 wheel notch' produces a delta of around 0.1, and that */
@ -3926,14 +3959,13 @@ void Window_ProcessEvents(void) {
if (GetMouseCoords(&x, &y)) Pointer_SetPosition(0, x, y); if (GetMouseCoords(&x, &y)) Pointer_SetPosition(0, x, y);
if (Input_RawMode) { if (Input_RawMode) {
dx = Send_CGFloat(ev, sel_registerName("deltaX")); dx = Send_CGFloat(ev, selDeltaX);
dy = Send_CGFloat(ev, sel_registerName("deltaY")); dy = Send_CGFloat(ev, selDeltaY);
Event_RaiseMove(&PointerEvents.RawMoved, 0, dx, dy); Event_RaiseMove(&PointerEvents.RawMoved, 0, dx, dy);
} }
break; break;
} }
objc_msgSend(appHandle, sel_registerName("sendEvent:"), ev); objc_msgSend(appHandle, selSendEvent, ev);
} }
} }
@ -3977,8 +4009,8 @@ static void View_DrawRect(id self, SEL cmd, CGRect r_) {
/* underlying data doesn't change what shows when drawing. */ /* underlying data doesn't change what shows when drawing. */
/* TODO: Find a better way of doing this in cocoa.. */ /* TODO: Find a better way of doing this in cocoa.. */
if (!fb_bmp.Scan0) return; if (!fb_bmp.Scan0) return;
nsContext = objc_msgSend((id)objc_getClass("NSGraphicsContext"), sel_registerName("currentContext")); nsContext = objc_msgSend((id)objc_getClass("NSGraphicsContext"), sel_currentContext);
context = objc_msgSend(nsContext, sel_registerName("graphicsPort")); context = objc_msgSend(nsContext, sel_graphicsPort);
/* TODO: Only update changed bit.. */ /* TODO: Only update changed bit.. */
rect.origin.x = 0; rect.origin.y = 0; rect.origin.x = 0; rect.origin.y = 0;
@ -4006,8 +4038,8 @@ void Window_DrawFramebuffer(Rect2D r) {
rect.size.width = r.Width; rect.size.width = r.Width;
rect.size.height = r.Height; rect.size.height = r.Height;
objc_msgSend(viewHandle, sel_registerName("setNeedsDisplayInRect:"), rect); objc_msgSend(viewHandle, selSetNeedsDisplay, rect);
objc_msgSend(viewHandle, sel_registerName("displayIfNeeded")); objc_msgSend(viewHandle, selDisplayIfNeeded);
} }
void Window_FreeFramebuffer(Bitmap* bmp) { void Window_FreeFramebuffer(Bitmap* bmp) {
@ -4054,12 +4086,12 @@ void GLContext_Init(struct GraphicsMode* mode) {
objc_msgSend(ctxHandle, sel_registerName("setView:"), viewHandle); objc_msgSend(ctxHandle, sel_registerName("setView:"), viewHandle);
objc_msgSend(fmt, sel_registerName("release")); objc_msgSend(fmt, sel_registerName("release"));
objc_msgSend(ctxHandle, sel_registerName("makeCurrentContext")); objc_msgSend(ctxHandle, sel_registerName("makeCurrentContext"));
objc_msgSend(ctxHandle, sel_registerName("update")); objc_msgSend(ctxHandle, selUpdate);
} }
void GLContext_Update(void) { void GLContext_Update(void) {
// TODO: Why does this crash on resizing // TODO: Why does this crash on resizing
objc_msgSend(ctxHandle, sel_registerName("update")); objc_msgSend(ctxHandle, selUpdate);
} }
void GLContext_Free(void) { void GLContext_Free(void) {
@ -4069,7 +4101,7 @@ void GLContext_Free(void) {
} }
bool GLContext_SwapBuffers(void) { bool GLContext_SwapBuffers(void) {
objc_msgSend(ctxHandle, sel_registerName("flushBuffer")); objc_msgSend(ctxHandle, selFlushBuffer);
return true; return true;
} }