bgfx/examples/common/entry/entry_osx.mm

333 lines
6 KiB
Text
Raw Normal View History

/*
2014-02-11 01:18:39 -05:00
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
2013-08-15 00:08:46 -04:00
#include "entry_p.h"
2013-08-15 00:08:46 -04:00
#if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_OSX
2013-08-08 01:50:01 -04:00
#import <Cocoa/Cocoa.h>
2013-08-08 02:11:20 -04:00
#include <bgfxplatform.h>
2013-08-08 01:50:01 -04:00
#include <bx/uint32_t.h>
#include <bx/thread.h>
#include <bx/os.h>
#define DEFAULT_WIDTH 1280
#define DEFAULT_HEIGHT 720
2013-07-22 00:53:20 -04:00
@interface AppDelegate : NSObject<NSApplicationDelegate>
{
bool terminated;
}
2013-07-22 00:53:20 -04:00
+ (AppDelegate *)sharedDelegate;
- (id)init;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (bool)applicationHasTerminated;
2013-07-22 00:53:20 -04:00
@end
2013-07-22 00:53:20 -04:00
@implementation AppDelegate
+ (AppDelegate *)sharedDelegate
{
static id delegate = [AppDelegate new];
return delegate;
}
2013-07-22 00:53:20 -04:00
- (id)init
{
self = [super init];
2013-07-22 00:53:20 -04:00
if (nil == self)
{
return nil;
}
2013-07-22 00:53:20 -04:00
self->terminated = false;
return self;
}
2013-07-22 00:53:20 -04:00
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
2013-12-07 13:19:54 -05:00
BX_UNUSED(sender);
self->terminated = true;
return NSTerminateCancel;
}
2013-07-22 00:53:20 -04:00
- (bool)applicationHasTerminated
{
return self->terminated;
}
2013-07-22 00:53:20 -04:00
@end
2013-07-22 00:53:20 -04:00
@interface Window : NSObject<NSWindowDelegate>
{
unsigned int windowCount;
}
2013-07-22 00:53:20 -04:00
+ (Window *)sharedDelegate;
- (id)init;
- (void)windowCreated:(NSWindow *)window;
- (BOOL)windowShouldClose:(NSWindow *)window;
2013-07-22 00:53:20 -04:00
@end
2013-07-22 00:53:20 -04:00
@implementation Window
+ (Window *)sharedDelegate
{
static id windowDelegate = [Window new];
return windowDelegate;
}
2013-07-22 00:53:20 -04:00
- (id)init
{
self = [super init];
2013-07-22 00:53:20 -04:00
if (nil == self)
{
return nil;
}
2013-07-22 00:53:20 -04:00
self->windowCount = 0;
return self;
}
2013-07-22 00:53:20 -04:00
- (void)windowCreated:(NSWindow *)window
{
assert(window);
2013-07-21 17:44:53 -04:00
[window setDelegate:self];
assert(self->windowCount < ~0u);
self->windowCount += 1;
}
2013-07-22 00:53:20 -04:00
- (BOOL)windowShouldClose:(NSWindow *)window
{
assert(window);
2013-07-21 17:44:53 -04:00
[window setDelegate:nil];
assert(self->windowCount);
self->windowCount -= 1;
2013-07-21 17:44:53 -04:00
2013-07-22 00:53:20 -04:00
if (self->windowCount == 0)
{
[NSApp terminate:self];
return false;
}
2013-07-22 00:53:20 -04:00
return true;
}
@end
namespace entry
{
struct MainThreadEntry
{
int m_argc;
char** m_argv;
2013-07-21 17:44:53 -04:00
static int32_t threadFunc(void* _userData)
{
MainThreadEntry* self = (MainThreadEntry*)_userData;
2013-08-08 01:50:01 -04:00
return main(self->m_argc, self->m_argv);
}
};
2013-07-21 17:44:53 -04:00
struct Context
{
Context()
: m_exit(false)
{
}
2013-07-21 17:44:53 -04:00
NSEvent* waitEvent()
2013-07-22 00:53:20 -04:00
{
return [NSApp
2013-07-21 17:44:53 -04:00
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture] // wait for event
inMode:NSDefaultRunLoopMode
2013-07-22 00:53:20 -04:00
dequeue:YES
];
}
2013-07-21 17:44:53 -04:00
NSEvent* peekEvent()
2013-07-22 00:53:20 -04:00
{
return [NSApp
2013-07-21 17:44:53 -04:00
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast] // do not wait for event
inMode:NSDefaultRunLoopMode
2013-07-22 00:53:20 -04:00
dequeue:YES
];
}
2013-07-21 17:44:53 -04:00
bool dispatchEvent(NSEvent* event)
2013-07-22 00:53:20 -04:00
{
if (event)
{
[NSApp sendEvent:event];
[NSApp updateWindows];
return true;
}
2013-07-22 00:53:20 -04:00
return false;
}
2013-07-21 17:44:53 -04:00
2013-07-22 00:53:20 -04:00
int32_t run(int _argc, char** _argv)
{
2013-07-21 17:44:53 -04:00
[NSApplication sharedApplication];
2013-07-22 00:53:20 -04:00
id dg = [AppDelegate sharedDelegate];
[NSApp setDelegate:dg];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp activateIgnoringOtherApps:YES];
[NSApp finishLaunching];
2013-07-22 00:53:20 -04:00
[[NSNotificationCenter defaultCenter]
2013-07-21 17:44:53 -04:00
postNotificationName:NSApplicationWillFinishLaunchingNotification
object:NSApp];
2013-07-22 00:53:20 -04:00
[[NSNotificationCenter defaultCenter]
2013-07-21 17:44:53 -04:00
postNotificationName:NSApplicationDidFinishLaunchingNotification
object:NSApp];
id quitMenuItem = [NSMenuItem new];
[quitMenuItem
initWithTitle:@"Quit"
action:@selector(terminate:)
keyEquivalent:@"q"];
2013-07-22 00:53:20 -04:00
id appMenu = [NSMenu new];
[appMenu addItem:quitMenuItem];
2013-07-22 00:53:20 -04:00
id appMenuItem = [NSMenuItem new];
[appMenuItem setSubmenu:appMenu];
2013-07-22 00:53:20 -04:00
id menubar = [[NSMenu new] autorelease];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
2013-07-21 17:44:53 -04:00
NSRect rect = NSMakeRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
NSWindow* window = [NSWindow alloc];
[window
2013-07-21 17:44:53 -04:00
initWithContentRect:rect
styleMask:0
|NSTitledWindowMask
|NSClosableWindowMask
|NSMiniaturizableWindowMask
|NSResizableWindowMask
backing:NSBackingStoreBuffered defer:NO
];
NSString* appName = [[NSProcessInfo processInfo] processName];
[window setTitle:appName];
[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
[window makeKeyAndOrderFront:window];
// [window setContentView:nil];
[window setBackgroundColor:[NSColor blackColor]];
2013-07-22 00:53:20 -04:00
[[Window sharedDelegate] windowCreated:window];
2013-07-21 17:44:53 -04:00
bgfx::osxSetNSWindow(window);
2013-07-21 17:44:53 -04:00
MainThreadEntry mte;
mte.m_argc = _argc;
mte.m_argv = _argv;
2013-07-21 17:44:53 -04:00
bx::Thread thread;
thread.init(mte.threadFunc, &mte);
2013-07-22 00:53:20 -04:00
while (!(m_exit = [dg applicationHasTerminated]) )
{
if (bgfx::RenderFrame::Exiting == bgfx::renderFrame() )
{
break;
}
while (dispatchEvent(peekEvent() ) )
{
}
}
m_eventQueue.postExitEvent();
2013-07-21 17:44:53 -04:00
2013-12-07 13:19:54 -05:00
while (bgfx::RenderFrame::NoContext != bgfx::renderFrame() ) {};
thread.shutdown();
2013-07-21 17:44:53 -04:00
return 0;
}
2013-07-21 17:44:53 -04:00
EventQueue m_eventQueue;
2013-07-21 17:44:53 -04:00
bool m_exit;
};
2013-07-21 17:44:53 -04:00
static Context s_ctx;
2013-07-21 17:44:53 -04:00
const Event* poll()
{
return s_ctx.m_eventQueue.poll();
}
2014-09-22 22:34:10 -04:00
const Event* poll(WindowHandle _handle)
{
return s_ctx.m_eventQueue.poll(_handle);
}
void release(const Event* _event)
{
s_ctx.m_eventQueue.release(_event);
}
2014-09-22 22:34:10 -04:00
WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
{
BX_UNUSED(_x, _y, _width, _height, _flags, _title);
WindowHandle handle = { UINT16_MAX };
return handle;
}
void destroyWindow(WindowHandle _handle)
{
BX_UNUSED(_handle);
}
void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
{
BX_UNUSED(_handle, _x, _y);
}
2014-09-19 13:33:13 -04:00
void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
{
2014-09-19 13:33:13 -04:00
BX_UNUSED(_handle, _width, _height);
}
2014-09-19 13:33:13 -04:00
void setWindowTitle(WindowHandle _handle, const char* _title)
2014-08-05 15:57:52 -04:00
{
2014-09-19 13:33:13 -04:00
BX_UNUSED(_handle, _title);
2014-08-05 15:57:52 -04:00
}
2014-09-19 13:33:13 -04:00
void toggleWindowFrame(WindowHandle _handle)
{
2014-09-19 13:33:13 -04:00
BX_UNUSED(_handle);
}
2014-09-19 13:33:13 -04:00
void setMouseLock(WindowHandle _handle, bool _lock)
2013-01-19 03:22:25 -05:00
{
2014-09-19 13:33:13 -04:00
BX_UNUSED(_handle, _lock);
2013-01-19 03:22:25 -05:00
}
} // namespace entry
int main(int _argc, char** _argv)
{
using namespace entry;
2013-07-22 00:53:20 -04:00
return s_ctx.run(_argc, _argv);
}
#endif // BX_PLATFORM_OSX