update osx project
This commit is contained in:
@@ -17,9 +17,6 @@
|
||||
#include <deque>
|
||||
#include <chrono>
|
||||
|
||||
std::deque<std::packaged_task<void()>> tasklist;
|
||||
std::mutex task_mutex;
|
||||
|
||||
@implementation View
|
||||
{
|
||||
NSSharingService *airdrop_service;
|
||||
@@ -192,136 +189,48 @@ std::mutex task_mutex;
|
||||
}
|
||||
- (void)prepareOpenGL
|
||||
{
|
||||
[super prepareOpenGL];
|
||||
|
||||
NSLog(@"prepare");
|
||||
|
||||
// Synchronize buffer swaps with vertical refresh rate
|
||||
GLint swapInt = 1;
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
// Create a display link capable of being used with all active displays
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&dl);
|
||||
|
||||
// Set the renderer output callback function
|
||||
CVDisplayLinkSetOutputCallback(dl, &MyDisplayLinkCallback, (__bridge void*)self);
|
||||
|
||||
// Set the display link for the current renderer
|
||||
CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
|
||||
CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
|
||||
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(dl, cglContext, cglPixelFormat);
|
||||
|
||||
CGLEnable([self.openGLContext CGLContextObj], kCGLCECrashOnRemovedFunctions);
|
||||
|
||||
// Activate the display link
|
||||
CVDisplayLinkStart(dl);
|
||||
|
||||
cgl = [[self openGLContext] CGLContextObj];
|
||||
glctx = [self openGLContext];
|
||||
|
||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||
App::I.init();
|
||||
[self.window setTitle:[NSString stringWithFormat:@"%s - %s", g_window_title, glGetString(GL_RENDERER)]];
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
gl_ready = true;
|
||||
|
||||
App::I->render_thread_start();
|
||||
App::I->render_sync();
|
||||
|
||||
if ([file2open length] > 0)
|
||||
{
|
||||
LOG("open file %s", [file2open UTF8String]);
|
||||
App::I.open_document([file2open UTF8String]);
|
||||
std::string s = [file2open UTF8String];
|
||||
App::I->render_task([=]
|
||||
{
|
||||
LOG("open file %s", s.c_str());
|
||||
App::I->open_document(s);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)terminateGL
|
||||
{
|
||||
CVDisplayLinkRelease(dl);
|
||||
App::I.terminate();
|
||||
}
|
||||
|
||||
// This is the renderer output callback function
|
||||
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now,
|
||||
const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
|
||||
{
|
||||
CVReturn result = [(__bridge View*)displayLinkContext getFrameForTime:outputTime];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
|
||||
{
|
||||
static double _timeFreq = CVGetHostClockFrequency();
|
||||
static double _prevTime = (double)outputTime->hostTime / _timeFreq;
|
||||
static double elapsed = 0;
|
||||
double hostTime = (double)outputTime->hostTime;
|
||||
double now = hostTime / _timeFreq;
|
||||
double dt = now - _prevTime;
|
||||
_prevTime = now;
|
||||
|
||||
// this will not update unless 1/30th of a second has passed since the last update
|
||||
//if (now < _prevTime + (1.0 / 30.0))
|
||||
{
|
||||
std::deque<std::packaged_task<void()>> working_list;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
working_list = std::move(tasklist);
|
||||
}
|
||||
|
||||
// We draw on a secondary thread through the display link
|
||||
// When resizing the view, -reshape is called automatically on the main
|
||||
// thread. Add a mutex around to avoid the threads accessing the context
|
||||
// simultaneously when resizing
|
||||
CGLLockContext([glctx CGLContextObj]);
|
||||
[glctx makeCurrentContext];
|
||||
|
||||
while (!working_list.empty())
|
||||
{
|
||||
working_list.front()();
|
||||
working_list.pop_front();
|
||||
}
|
||||
|
||||
App::I.tick(dt);
|
||||
|
||||
if (App::I.redraw)
|
||||
{
|
||||
App::I.clear();
|
||||
App::I.update(elapsed);
|
||||
elapsed = 0;
|
||||
CGLFlushDrawable([glctx CGLContextObj]);
|
||||
}
|
||||
|
||||
//[[self openGLContext] flushBuffer];
|
||||
// returning NO will cause the layer to NOT be redrawn
|
||||
|
||||
CGLUnlockContext([glctx CGLContextObj]);
|
||||
return NO;
|
||||
}
|
||||
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// Release the display link
|
||||
CVDisplayLinkRelease(dl);
|
||||
App::I->ui_thread_stop();
|
||||
App::I->render_thread_stop();
|
||||
App::I->terminate();
|
||||
delete App::I;
|
||||
App::I = nullptr;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
NSLog(@"drawRect");
|
||||
|
||||
// We draw on a secondary thread through the display link
|
||||
// When resizing the view, -reshape is called automatically on the main
|
||||
// thread. Add a mutex around to avoid the threads accessing the context
|
||||
// simultaneously when resizing
|
||||
CGLLockContext(cgl);
|
||||
[glctx makeCurrentContext];
|
||||
|
||||
App::I.redraw = true;
|
||||
App::I.clear();
|
||||
App::I.update(0);
|
||||
|
||||
//[[self openGLContext] flushBuffer];
|
||||
// returning NO will cause the layer to NOT be redrawn
|
||||
|
||||
CGLFlushDrawable(cgl);
|
||||
CGLUnlockContext(cgl);
|
||||
return;
|
||||
}
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
@@ -343,7 +252,6 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
// resizing the view, -drawRect is called on the main thread.
|
||||
// Add a mutex around to avoid the threads accessing the context
|
||||
// simultaneously when resizing.
|
||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||
|
||||
#if SUPPORT_RETINA_RESOLUTION
|
||||
|
||||
@@ -371,9 +279,10 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
NSRect viewRectPixels = viewRectPoints;
|
||||
|
||||
#endif // !SUPPORT_RETINA_RESOLUTION
|
||||
App::I.resize(viewRectPixels.size.width, viewRectPixels.size.height);
|
||||
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->resize(viewRectPixels.size.width, viewRectPixels.size.height);
|
||||
});
|
||||
}
|
||||
- (void)renewGState
|
||||
{
|
||||
@@ -391,57 +300,50 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc,p=theEvent.pressure] {
|
||||
App::I.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||
App::I->mouse_down(0, mouseLoc.x, App::I->height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
- (void)rightMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc,p=theEvent.pressure] {
|
||||
App::I.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||
App::I->mouse_down(1, mouseLoc.x, App::I->height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
- (void)mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc] {
|
||||
App::I.mouse_up(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc] {
|
||||
App::I->mouse_up(0, mouseLoc.x, App::I->height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
- (void)rightMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc] {
|
||||
App::I.mouse_up(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc] {
|
||||
App::I->mouse_up(1, mouseLoc.x, App::I->height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
- (void)mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc,p=theEvent.pressure] {
|
||||
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||
App::I->mouse_move(mouseLoc.x, App::I->height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
-(void)mouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc,p=theEvent.pressure] {
|
||||
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||
App::I->mouse_move(mouseLoc.x, App::I->height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
- (void)rightMouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc,p=theEvent.pressure] {
|
||||
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||
App::I->mouse_move(mouseLoc.x, App::I->height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
||||
});
|
||||
}
|
||||
-(void)mouseExited:(NSEvent *)event
|
||||
@@ -459,9 +361,8 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
- (void)scrollWheel:(NSEvent *)theEvent
|
||||
{
|
||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([mouseLoc,d=[theEvent deltaY]] {
|
||||
App::I.mouse_scroll(mouseLoc.x, App::I.height - mouseLoc.y - 1, d);
|
||||
App::I->ui_task_async([mouseLoc,d=[theEvent deltaY]] {
|
||||
App::I->mouse_scroll(mouseLoc.x, App::I->height - mouseLoc.y - 1, d);
|
||||
});
|
||||
}
|
||||
- (void)keyDown:(NSEvent *)theEvent
|
||||
@@ -470,27 +371,25 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
auto chars = [theEvent characters];
|
||||
const char* c_str = [chars cStringUsingEncoding:NSASCIIStringEncoding];
|
||||
std::string s = c_str ? c_str : "";
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([keyCode, s] {
|
||||
if (App::I.keys[(int)kKey::KeyCtrl])
|
||||
App::I->ui_task_async([keyCode, s] {
|
||||
if (App::I->keys[(int)kKey::KeyCtrl])
|
||||
{
|
||||
App::I.key_down(convert_key(keyCode));
|
||||
App::I.key_up(convert_key(keyCode));
|
||||
App::I->key_down(convert_key(keyCode));
|
||||
App::I->key_up(convert_key(keyCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
App::I.key_down(convert_key(keyCode));
|
||||
App::I->key_down(convert_key(keyCode));
|
||||
if (!s.empty())
|
||||
App::I.key_char(s[0]);
|
||||
App::I->key_char(s[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
- (void)keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
auto keyCode = [theEvent keyCode];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([keyCode] {
|
||||
App::I.key_up(convert_key(keyCode));
|
||||
App::I->ui_task_async([keyCode] {
|
||||
App::I->key_up(convert_key(keyCode));
|
||||
});
|
||||
}
|
||||
- (void)flagsChanged:(NSEvent *)event
|
||||
@@ -498,25 +397,24 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
[super flagsChanged:event];
|
||||
|
||||
auto flags = [event modifierFlags];
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([flags] {
|
||||
App::I->ui_task_async([flags] {
|
||||
static bool pressed_shift = false;
|
||||
if (pressed_shift != (flags & NSShiftKeyMask))
|
||||
{
|
||||
pressed_shift = (flags & NSShiftKeyMask);
|
||||
pressed_shift ? App::I.key_down(kKey::KeyShift) : App::I.key_up(kKey::KeyShift);
|
||||
pressed_shift ? App::I->key_down(kKey::KeyShift) : App::I->key_up(kKey::KeyShift);
|
||||
}
|
||||
static bool pressed_alt = false;
|
||||
if (pressed_alt != (flags & NSAlternateKeyMask))
|
||||
{
|
||||
pressed_alt = (flags & NSAlternateKeyMask);
|
||||
pressed_alt ? App::I.key_down(kKey::KeyAlt) : App::I.key_up(kKey::KeyAlt);
|
||||
pressed_alt ? App::I->key_down(kKey::KeyAlt) : App::I->key_up(kKey::KeyAlt);
|
||||
}
|
||||
static bool pressed_cmd = false;
|
||||
if (pressed_cmd != (flags & NSCommandKeyMask))
|
||||
{
|
||||
pressed_cmd = (flags & NSCommandKeyMask);
|
||||
pressed_cmd ? App::I.key_down(kKey::KeyCtrl) : App::I.key_up(kKey::KeyCtrl);
|
||||
pressed_cmd ? App::I->key_down(kKey::KeyCtrl) : App::I->key_up(kKey::KeyCtrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -532,7 +430,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
}
|
||||
-(BOOL)windowShouldClose:(NSWindow *)sender
|
||||
{
|
||||
return App::I.request_close();
|
||||
return App::I->request_close();
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -555,7 +453,12 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
{
|
||||
LOG("open file %s", [filename UTF8String]);
|
||||
if (view && view->gl_ready)
|
||||
App::I.open_document([filename UTF8String]);
|
||||
{
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->open_document([filename UTF8String]);
|
||||
});
|
||||
}
|
||||
file2open = filename;
|
||||
return YES;
|
||||
}
|
||||
@@ -572,17 +475,18 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
// Do some additional configuration if needed here
|
||||
[[BITHockeyManager sharedHockeyManager] startManager];
|
||||
|
||||
if (!App::I.check_license())
|
||||
if (!App::I->check_license())
|
||||
return;
|
||||
|
||||
App::I.initLog();
|
||||
App::I.create();
|
||||
NSRect r = NSMakeRect(0, 0, App::I.width, App::I.height);
|
||||
App::I = new App;
|
||||
App::I->initLog();
|
||||
App::I->create();
|
||||
NSRect r = NSMakeRect(0, 0, App::I->width, App::I->height);
|
||||
|
||||
view = [[View alloc] initWithFrame:r];
|
||||
view->file2open = file2open;
|
||||
controller = [[Controller alloc] initWithWindow:window];
|
||||
App::I.osx_view = view;
|
||||
App::I->osx_view = view;
|
||||
|
||||
auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask;
|
||||
window = [[Window alloc] initWithContentRect:r styleMask:style backing:NSBackingStoreBuffered defer:NO];
|
||||
@@ -609,6 +513,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
||||
[appMenuItem setSubmenu:appMenu];
|
||||
|
||||
NSLog(@"app launched");
|
||||
App::I->ui_thread_start();
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
@interface View : NSOpenGLView<NSSharingServiceDelegate>
|
||||
{
|
||||
@public Window* wnd;
|
||||
CVDisplayLinkRef dl;
|
||||
NSOpenGLContext* glctx;
|
||||
_CGLContextObject* cgl;
|
||||
bool gl_ready;
|
||||
|
||||
Reference in New Issue
Block a user