bgfx/examples/common/entry_osx.mm
2013-01-19 00:22:25 -08:00

251 lines
5.1 KiB
Text
Executable file

/*
* Copyright 2011-2013 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include <bx/bx.h>
#if BX_PLATFORM_OSX
#include <bgfxplatform.h>
#include <bx/uint32_t.h>
#include <bx/thread.h>
#include "entry.h"
#include "dbg.h"
#define DEFAULT_WIDTH 1280
#define DEFAULT_HEIGHT 720
extern int _main_(int _argc, char** _argv);
@interface bgfxApplicationDelegate : NSObject <NSApplicationDelegate> {
bool terminated;
}
+ (bgfxApplicationDelegate *)sharedDelegate;
- (id)init;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (bool)applicationHasTerminated;
@end
@implementation bgfxApplicationDelegate
+ (bgfxApplicationDelegate *)sharedDelegate {
static id delegate = [bgfxApplicationDelegate new];
return delegate;
}
- (id)init {
self = [super init];
if (self) {
self->terminated = false;
}
return self;
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
self->terminated = true;
return NSTerminateCancel;
}
- (bool)applicationHasTerminated {
return self->terminated;
}
@end
@interface bgfxWindowDelegate : NSObject <NSWindowDelegate> {
unsigned int windowCount;
}
+ (bgfxWindowDelegate *)sharedDelegate;
- (id)init;
- (void)windowCreated:(NSWindow *)window;
- (BOOL)windowShouldClose:(NSWindow *)window;
@end
@implementation bgfxWindowDelegate
+ (bgfxWindowDelegate *)sharedDelegate {
static id windowDelegate = [bgfxWindowDelegate new];
return windowDelegate;
}
- (id)init {
self = [super init];
if (self) {
self->windowCount = 0;
}
return self;
}
- (void)windowCreated:(NSWindow *)window {
assert(window);
[window setDelegate:self];
assert(self->windowCount < ~0u);
self->windowCount += 1;
}
- (BOOL)windowShouldClose:(NSWindow *)window {
assert(window);
[window setDelegate:nil];
assert(self->windowCount);
self->windowCount -= 1;
if (self->windowCount == 0) {
[NSApp terminate:self];
return false;
}
return true;
}
@end
namespace entry
{
struct MainThreadEntry
{
int m_argc;
char** m_argv;
static int32_t threadFunc(void* _userData)
{
MainThreadEntry* self = (MainThreadEntry*)_userData;
return _main_(self->m_argc, self->m_argv);
}
};
struct Context
{
Context()
: m_exit(false)
{
}
NSEvent* WaitEvent () {
return
[NSApp
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture] // wait for event
inMode:NSDefaultRunLoopMode
dequeue:YES];
}
NSEvent* PeekEvent () {
return
[NSApp
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast] // do not wait for event
inMode:NSDefaultRunLoopMode
dequeue:YES];
}
bool DispatchEvent (NSEvent* event) {
if (event) {
[NSApp sendEvent:event];
[NSApp updateWindows];
return true;
}
return false;
}
int32_t main(int _argc, char** _argv)
{
[NSApplication sharedApplication];
id dg = [bgfxApplicationDelegate sharedDelegate];
[NSApp setDelegate:dg];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp activateIgnoringOtherApps:YES];
[NSApp finishLaunching];
[[NSNotificationCenter defaultCenter]
postNotificationName:NSApplicationWillFinishLaunchingNotification
object:NSApp];
[[NSNotificationCenter defaultCenter]
postNotificationName:NSApplicationDidFinishLaunchingNotification
object:NSApp];
id quitMenuItem = [NSMenuItem new];
[quitMenuItem
initWithTitle:@"Quit"
action:@selector(terminate:)
keyEquivalent:@"q"];
id appMenu = [NSMenu new];
[appMenu addItem:quitMenuItem];
id appMenuItem = [NSMenuItem new];
[appMenuItem setSubmenu:appMenu];
id menubar = [[NSMenu new] autorelease];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
NSRect rect = NSMakeRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
NSWindow* window = [NSWindow alloc];
[window
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:nil];
[[bgfxWindowDelegate sharedDelegate] windowCreated:window];
bgfx::osxSetNSWindow(window);
MainThreadEntry mte;
mte.m_argc = _argc;
mte.m_argv = _argv;
bx::Thread thread;
thread.init(mte.threadFunc, &mte);
while (!(m_exit = [dg applicationHasTerminated]))
{
DispatchEvent(WaitEvent());
while (DispatchEvent(PeekEvent()));
}
thread.shutdown();
return 0;
}
bool m_exit;
};
static Context s_ctx;
const Event* poll()
{
return NULL;
}
void release(const Event* _event)
{
}
void setWindowSize(uint32_t _width, uint32_t _height)
{
}
void toggleWindowFrame()
{
}
void setMouseLock(bool _lock)
{
}
} // namespace entry
int main(int _argc, char** _argv)
{
using namespace entry;
return s_ctx.main(_argc, _argv);
}
#endif // BX_PLATFORM_OSX