update osx project
This commit is contained in:
@@ -17,9 +17,6 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
std::deque<std::packaged_task<void()>> tasklist;
|
|
||||||
std::mutex task_mutex;
|
|
||||||
|
|
||||||
@implementation View
|
@implementation View
|
||||||
{
|
{
|
||||||
NSSharingService *airdrop_service;
|
NSSharingService *airdrop_service;
|
||||||
@@ -192,136 +189,48 @@ std::mutex task_mutex;
|
|||||||
}
|
}
|
||||||
- (void)prepareOpenGL
|
- (void)prepareOpenGL
|
||||||
{
|
{
|
||||||
|
[super prepareOpenGL];
|
||||||
|
|
||||||
NSLog(@"prepare");
|
NSLog(@"prepare");
|
||||||
|
|
||||||
// Synchronize buffer swaps with vertical refresh rate
|
// Synchronize buffer swaps with vertical refresh rate
|
||||||
GLint swapInt = 1;
|
GLint swapInt = 1;
|
||||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
[[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];
|
cgl = [[self openGLContext] CGLContextObj];
|
||||||
glctx = [self openGLContext];
|
glctx = [self openGLContext];
|
||||||
|
|
||||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||||
App::I.init();
|
|
||||||
[self.window setTitle:[NSString stringWithFormat:@"%s - %s", g_window_title, glGetString(GL_RENDERER)]];
|
[self.window setTitle:[NSString stringWithFormat:@"%s - %s", g_window_title, glGetString(GL_RENDERER)]];
|
||||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||||
gl_ready = true;
|
gl_ready = true;
|
||||||
|
|
||||||
|
App::I->render_thread_start();
|
||||||
|
App::I->render_sync();
|
||||||
|
|
||||||
if ([file2open length] > 0)
|
if ([file2open length] > 0)
|
||||||
{
|
{
|
||||||
LOG("open file %s", [file2open UTF8String]);
|
std::string s = [file2open UTF8String];
|
||||||
App::I.open_document([file2open UTF8String]);
|
App::I->render_task([=]
|
||||||
|
{
|
||||||
|
LOG("open file %s", s.c_str());
|
||||||
|
App::I->open_document(s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)terminateGL
|
- (void)terminateGL
|
||||||
{
|
{
|
||||||
CVDisplayLinkRelease(dl);
|
App::I->ui_thread_stop();
|
||||||
App::I.terminate();
|
App::I->render_thread_stop();
|
||||||
}
|
App::I->terminate();
|
||||||
|
delete App::I;
|
||||||
// This is the renderer output callback function
|
App::I = nullptr;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)drawRect:(NSRect)dirtyRect
|
- (void)drawRect:(NSRect)dirtyRect
|
||||||
{
|
{
|
||||||
NSLog(@"drawRect");
|
return;
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
- (void)updateTrackingAreas
|
- (void)updateTrackingAreas
|
||||||
{
|
{
|
||||||
@@ -343,7 +252,6 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
// resizing the view, -drawRect is called on the main thread.
|
// resizing the view, -drawRect is called on the main thread.
|
||||||
// Add a mutex around to avoid the threads accessing the context
|
// Add a mutex around to avoid the threads accessing the context
|
||||||
// simultaneously when resizing.
|
// simultaneously when resizing.
|
||||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
|
||||||
|
|
||||||
#if SUPPORT_RETINA_RESOLUTION
|
#if SUPPORT_RETINA_RESOLUTION
|
||||||
|
|
||||||
@@ -371,9 +279,10 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
NSRect viewRectPixels = viewRectPoints;
|
NSRect viewRectPixels = viewRectPoints;
|
||||||
|
|
||||||
#endif // !SUPPORT_RETINA_RESOLUTION
|
#endif // !SUPPORT_RETINA_RESOLUTION
|
||||||
App::I.resize(viewRectPixels.size.width, viewRectPixels.size.height);
|
App::I->ui_task_async([=]
|
||||||
|
{
|
||||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
App::I->resize(viewRectPixels.size.width, viewRectPixels.size.height);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
- (void)renewGState
|
- (void)renewGState
|
||||||
{
|
{
|
||||||
@@ -391,57 +300,50 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
- (void)mouseDown:(NSEvent *)theEvent
|
- (void)mouseDown:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||||
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.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)rightMouseDown:(NSEvent *)theEvent
|
- (void)rightMouseDown:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||||
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.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)mouseUp:(NSEvent *)theEvent
|
- (void)mouseUp:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc] {
|
||||||
tasklist.emplace_back([mouseLoc] {
|
App::I->mouse_up(0, mouseLoc.x, App::I->height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
||||||
App::I.mouse_up(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)rightMouseUp:(NSEvent *)theEvent
|
- (void)rightMouseUp:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc] {
|
||||||
tasklist.emplace_back([mouseLoc] {
|
App::I->mouse_up(1, mouseLoc.x, App::I->height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
||||||
App::I.mouse_up(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)mouseMoved:(NSEvent *)theEvent
|
- (void)mouseMoved:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||||
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.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
-(void)mouseDragged:(NSEvent *)theEvent
|
-(void)mouseDragged:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||||
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.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)rightMouseDragged:(NSEvent *)theEvent
|
- (void)rightMouseDragged:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc,p=theEvent.pressure] {
|
||||||
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.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
-(void)mouseExited:(NSEvent *)event
|
-(void)mouseExited:(NSEvent *)event
|
||||||
@@ -459,9 +361,8 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
- (void)scrollWheel:(NSEvent *)theEvent
|
- (void)scrollWheel:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([mouseLoc,d=[theEvent deltaY]] {
|
||||||
tasklist.emplace_back([mouseLoc,d=[theEvent deltaY]] {
|
App::I->mouse_scroll(mouseLoc.x, App::I->height - mouseLoc.y - 1, d);
|
||||||
App::I.mouse_scroll(mouseLoc.x, App::I.height - mouseLoc.y - 1, d);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)keyDown:(NSEvent *)theEvent
|
- (void)keyDown:(NSEvent *)theEvent
|
||||||
@@ -470,27 +371,25 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
auto chars = [theEvent characters];
|
auto chars = [theEvent characters];
|
||||||
const char* c_str = [chars cStringUsingEncoding:NSASCIIStringEncoding];
|
const char* c_str = [chars cStringUsingEncoding:NSASCIIStringEncoding];
|
||||||
std::string s = c_str ? c_str : "";
|
std::string s = c_str ? c_str : "";
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([keyCode, s] {
|
||||||
tasklist.emplace_back([keyCode, s] {
|
if (App::I->keys[(int)kKey::KeyCtrl])
|
||||||
if (App::I.keys[(int)kKey::KeyCtrl])
|
|
||||||
{
|
{
|
||||||
App::I.key_down(convert_key(keyCode));
|
App::I->key_down(convert_key(keyCode));
|
||||||
App::I.key_up(convert_key(keyCode));
|
App::I->key_up(convert_key(keyCode));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
App::I.key_down(convert_key(keyCode));
|
App::I->key_down(convert_key(keyCode));
|
||||||
if (!s.empty())
|
if (!s.empty())
|
||||||
App::I.key_char(s[0]);
|
App::I->key_char(s[0]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)keyUp:(NSEvent *)theEvent
|
- (void)keyUp:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
auto keyCode = [theEvent keyCode];
|
auto keyCode = [theEvent keyCode];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([keyCode] {
|
||||||
tasklist.emplace_back([keyCode] {
|
App::I->key_up(convert_key(keyCode));
|
||||||
App::I.key_up(convert_key(keyCode));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
- (void)flagsChanged:(NSEvent *)event
|
- (void)flagsChanged:(NSEvent *)event
|
||||||
@@ -498,25 +397,24 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
[super flagsChanged:event];
|
[super flagsChanged:event];
|
||||||
|
|
||||||
auto flags = [event modifierFlags];
|
auto flags = [event modifierFlags];
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I->ui_task_async([flags] {
|
||||||
tasklist.emplace_back([flags] {
|
|
||||||
static bool pressed_shift = false;
|
static bool pressed_shift = false;
|
||||||
if (pressed_shift != (flags & NSShiftKeyMask))
|
if (pressed_shift != (flags & NSShiftKeyMask))
|
||||||
{
|
{
|
||||||
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;
|
static bool pressed_alt = false;
|
||||||
if (pressed_alt != (flags & NSAlternateKeyMask))
|
if (pressed_alt != (flags & NSAlternateKeyMask))
|
||||||
{
|
{
|
||||||
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;
|
static bool pressed_cmd = false;
|
||||||
if (pressed_cmd != (flags & NSCommandKeyMask))
|
if (pressed_cmd != (flags & NSCommandKeyMask))
|
||||||
{
|
{
|
||||||
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
|
-(BOOL)windowShouldClose:(NSWindow *)sender
|
||||||
{
|
{
|
||||||
return App::I.request_close();
|
return App::I->request_close();
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -555,7 +453,12 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
{
|
{
|
||||||
LOG("open file %s", [filename UTF8String]);
|
LOG("open file %s", [filename UTF8String]);
|
||||||
if (view && view->gl_ready)
|
if (view && view->gl_ready)
|
||||||
App::I.open_document([filename UTF8String]);
|
{
|
||||||
|
App::I->ui_task_async([=]
|
||||||
|
{
|
||||||
|
App::I->open_document([filename UTF8String]);
|
||||||
|
});
|
||||||
|
}
|
||||||
file2open = filename;
|
file2open = filename;
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@@ -572,17 +475,18 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
// Do some additional configuration if needed here
|
// Do some additional configuration if needed here
|
||||||
[[BITHockeyManager sharedHockeyManager] startManager];
|
[[BITHockeyManager sharedHockeyManager] startManager];
|
||||||
|
|
||||||
if (!App::I.check_license())
|
if (!App::I->check_license())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
App::I.initLog();
|
App::I = new App;
|
||||||
App::I.create();
|
App::I->initLog();
|
||||||
NSRect r = NSMakeRect(0, 0, App::I.width, App::I.height);
|
App::I->create();
|
||||||
|
NSRect r = NSMakeRect(0, 0, App::I->width, App::I->height);
|
||||||
|
|
||||||
view = [[View alloc] initWithFrame:r];
|
view = [[View alloc] initWithFrame:r];
|
||||||
view->file2open = file2open;
|
view->file2open = file2open;
|
||||||
controller = [[Controller alloc] initWithWindow:window];
|
controller = [[Controller alloc] initWithWindow:window];
|
||||||
App::I.osx_view = view;
|
App::I->osx_view = view;
|
||||||
|
|
||||||
auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask;
|
auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask;
|
||||||
window = [[Window alloc] initWithContentRect:r styleMask:style backing:NSBackingStoreBuffered defer:NO];
|
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];
|
[appMenuItem setSubmenu:appMenu];
|
||||||
|
|
||||||
NSLog(@"app launched");
|
NSLog(@"app launched");
|
||||||
|
App::I->ui_thread_start();
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
@interface View : NSOpenGLView<NSSharingServiceDelegate>
|
@interface View : NSOpenGLView<NSSharingServiceDelegate>
|
||||||
{
|
{
|
||||||
@public Window* wnd;
|
@public Window* wnd;
|
||||||
CVDisplayLinkRef dl;
|
|
||||||
NSOpenGLContext* glctx;
|
NSOpenGLContext* glctx;
|
||||||
_CGLContextObject* cgl;
|
_CGLContextObject* cgl;
|
||||||
bool gl_ready;
|
bool gl_ready;
|
||||||
|
|||||||
14
src/app.cpp
14
src/app.cpp
@@ -24,6 +24,20 @@ void destroy_window();
|
|||||||
|
|
||||||
App* App::I = nullptr; // singleton
|
App* App::I = nullptr; // singleton
|
||||||
|
|
||||||
|
std::deque<std::packaged_task<void()>> App::render_tasklist;
|
||||||
|
std::mutex App::render_task_mutex;
|
||||||
|
std::condition_variable App::render_cv;
|
||||||
|
std::thread App::render_thread;
|
||||||
|
std::thread::id App::render_thread_id;
|
||||||
|
bool App::render_running = false;
|
||||||
|
|
||||||
|
std::deque<std::packaged_task<void()>> App::ui_tasklist;
|
||||||
|
std::mutex App::ui_task_mutex;
|
||||||
|
std::condition_variable App::ui_cv;
|
||||||
|
std::thread App::ui_thread;
|
||||||
|
std::thread::id App::ui_thread_id;
|
||||||
|
bool App::ui_running = false;
|
||||||
|
|
||||||
void App::create()
|
void App::create()
|
||||||
{
|
{
|
||||||
width = 1920/2;
|
width = 1920/2;
|
||||||
|
|||||||
24
src/app.h
24
src/app.h
@@ -256,12 +256,12 @@ public:
|
|||||||
// RENDER THREAD
|
// RENDER THREAD
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::deque<std::packaged_task<void()>> render_tasklist;
|
static std::deque<std::packaged_task<void()>> render_tasklist;
|
||||||
std::mutex render_task_mutex;
|
static std::mutex render_task_mutex;
|
||||||
std::condition_variable render_cv;
|
static std::condition_variable render_cv;
|
||||||
std::thread render_thread;
|
static std::thread render_thread;
|
||||||
std::thread::id render_thread_id;
|
static std::thread::id render_thread_id;
|
||||||
bool render_running = false;
|
static bool render_running;
|
||||||
void render_thread_main();
|
void render_thread_main();
|
||||||
void render_thread_start();
|
void render_thread_start();
|
||||||
void render_thread_stop();
|
void render_thread_stop();
|
||||||
@@ -322,12 +322,12 @@ public:
|
|||||||
// UI THREAD
|
// UI THREAD
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::deque<std::packaged_task<void()>> ui_tasklist;
|
static std::deque<std::packaged_task<void()>> ui_tasklist;
|
||||||
std::mutex ui_task_mutex;
|
static std::mutex ui_task_mutex;
|
||||||
std::condition_variable ui_cv;
|
static std::condition_variable ui_cv;
|
||||||
std::thread ui_thread;
|
static std::thread ui_thread;
|
||||||
std::thread::id ui_thread_id;
|
static std::thread::id ui_thread_id;
|
||||||
bool ui_running = false;
|
static bool ui_running;
|
||||||
void ui_thread_main();
|
void ui_thread_main();
|
||||||
void ui_thread_start();
|
void ui_thread_start();
|
||||||
void ui_thread_stop();
|
void ui_thread_stop();
|
||||||
|
|||||||
@@ -508,13 +508,7 @@ void NodeStrokePreview::draw_stroke()
|
|||||||
s_running = true;
|
s_running = true;
|
||||||
s_renderer = std::thread([] {
|
s_renderer = std::thread([] {
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
#if __OSX__
|
|
||||||
// There's some weird multithread bug at startup
|
|
||||||
// This random wait is a temp fix
|
|
||||||
// Today is 25/05/2019
|
|
||||||
// Good luck, future Omar
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
||||||
#endif
|
|
||||||
m_sampler_linear.create();
|
m_sampler_linear.create();
|
||||||
m_sampler_linear_repeat.create(GL_LINEAR, GL_REPEAT);
|
m_sampler_linear_repeat.create(GL_LINEAR, GL_REPEAT);
|
||||||
m_sampler_mipmap.create();
|
m_sampler_mipmap.create();
|
||||||
@@ -553,6 +547,8 @@ void NodeStrokePreview::draw_stroke()
|
|||||||
|
|
||||||
gl.restore();
|
gl.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
node->app_redraw();
|
||||||
|
|
||||||
//std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
//std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <ctime>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
@implementation PathWithModDate
|
@implementation PathWithModDate
|
||||||
@@ -45,8 +48,15 @@ void exception_handler(NSException *exception)
|
|||||||
LOG("exception %s\n", [[exception name] cStringUsingEncoding:NSUTF8StringEncoding]);
|
LOG("exception %s\n", [[exception name] cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||||
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
||||||
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||||
if (App::I.canvas && App::I.canvas->m_canvas)
|
|
||||||
App::I.canvas->m_canvas->project_save_thread(App::I.data_path + "/recovery.ppi");
|
auto t = std::time(nullptr);
|
||||||
|
auto tm = *std::localtime(&t);
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S");
|
||||||
|
auto path = App::I->data_path + "/" + App::I->doc_name + "-recovery (" + oss.str() + ").ppi";
|
||||||
|
|
||||||
|
if (App::I->canvas && App::I->canvas->m_canvas)
|
||||||
|
App::I->canvas->m_canvas->project_save_thread(path);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,8 +66,15 @@ static void signal_handler (int signo) {
|
|||||||
LOG("signal %d\n", signo);
|
LOG("signal %d\n", signo);
|
||||||
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
||||||
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||||
if (App::I.canvas && App::I.canvas->m_canvas)
|
|
||||||
App::I.canvas->m_canvas->project_save_thread(App::I.data_path + "/recovery.ppi");
|
auto t = std::time(nullptr);
|
||||||
|
auto tm = *std::localtime(&t);
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S");
|
||||||
|
auto path = App::I->data_path + "/" + App::I->doc_name + "-recovery (" + oss.str() + ").ppi";
|
||||||
|
|
||||||
|
if (App::I->canvas && App::I->canvas->m_canvas)
|
||||||
|
App::I->canvas->m_canvas->project_save_thread(path);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ void Shape::draw_stroke() const
|
|||||||
|
|
||||||
void Shape::destroy()
|
void Shape::destroy()
|
||||||
{
|
{
|
||||||
App::I->render_task_async([b1=buffers[0],b2=buffers[1],a1=arrays[0],a2=arrays[1]]
|
if (App::I) App::I->render_task_async([b1=buffers[0],b2=buffers[1],a1=arrays[0],a2=arrays[1]]
|
||||||
{
|
{
|
||||||
if (b1 || b2)
|
if (b1 || b2)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user