update iOS project
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
||||
{
|
||||
App::I.open_document([url fileSystemRepresentation]);
|
||||
App::I->open_document([url fileSystemRepresentation]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -73,29 +73,29 @@
|
||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
App::I.redraw = true;
|
||||
App::I->redraw = true;
|
||||
[view reset_touch];
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
App::I.redraw = true;
|
||||
App::I->redraw = true;
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
App::I.redraw = true;
|
||||
App::I->redraw = true;
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
App::I.redraw = true;
|
||||
App::I->redraw = true;
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
App::I.redraw = true;
|
||||
App::I->redraw = true;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
- (void)unregisterForKeyboardNotifications;
|
||||
- (void)crash;
|
||||
- (void)share_file:(NSString*)file_path;
|
||||
- (void)tick;
|
||||
- (void)render_loop;
|
||||
- (std::string)clipboard_get_string;
|
||||
- (bool)clipboard_set_string:(const std::string&)s;
|
||||
@end
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "app.h"
|
||||
#import "objc_utils.h"
|
||||
|
||||
std::deque<std::packaged_task<void()>> tasklist;
|
||||
std::mutex task_mutex;
|
||||
std::mutex render_mutex;
|
||||
std::condition_variable render_cv;
|
||||
|
||||
@@ -30,9 +28,6 @@ std::condition_variable render_cv;
|
||||
NSLock* gl_lock;
|
||||
}
|
||||
@property (strong, nonatomic) EAGLContext *context;
|
||||
|
||||
- (void)setupGL;
|
||||
- (void)tearDownGL;
|
||||
@end
|
||||
|
||||
//std::map<
|
||||
@@ -82,6 +77,7 @@ std::recursive_mutex lock_mutex;
|
||||
- (void)async_swap
|
||||
{
|
||||
[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
[self->glview display];
|
||||
}
|
||||
|
||||
- (void)share_file:(NSString *)file_path
|
||||
@@ -144,12 +140,18 @@ std::recursive_mutex lock_mutex;
|
||||
- (void)insertText:(NSString *)text
|
||||
{
|
||||
if (const char* cstr = [text cStringUsingEncoding:NSASCIIStringEncoding])
|
||||
App::I.key_char(cstr[0]);
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->key_char(cstr[0]);
|
||||
});
|
||||
NSLog(@"%@", text);
|
||||
// Do something with the typed character
|
||||
}
|
||||
- (void)deleteBackward {
|
||||
App::I.key_char('\b');
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->key_char('\b');
|
||||
});
|
||||
// Handle the delete key
|
||||
}
|
||||
- (BOOL)hasText {
|
||||
@@ -192,13 +194,13 @@ std::recursive_mutex lock_mutex;
|
||||
|
||||
- (void)keyboardWillBeShown:(NSNotification*)aNotification
|
||||
{
|
||||
App::I.redraw = true;
|
||||
App::I.animate = true;
|
||||
App::I->redraw = true;
|
||||
App::I->animate = true;
|
||||
}
|
||||
- (void)keyboardWasHidden:(NSNotification*)aNotification
|
||||
{
|
||||
App::I.redraw = true;
|
||||
App::I.animate = false;
|
||||
App::I->redraw = true;
|
||||
App::I->animate = false;
|
||||
[self unregisterForKeyboardNotifications];
|
||||
}
|
||||
|
||||
@@ -213,11 +215,12 @@ std::recursive_mutex lock_mutex;
|
||||
frame.size.height -= kbSize.height;
|
||||
view.frame = frame;
|
||||
|
||||
[self async_lock];
|
||||
App::I.resize(frame.size.width * view.contentScaleFactor,
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->resize(frame.size.width * view.contentScaleFactor,
|
||||
frame.size.height * view.contentScaleFactor);
|
||||
App::I.animate = false;
|
||||
[self async_unlock];
|
||||
});
|
||||
App::I->animate = false;
|
||||
}
|
||||
|
||||
// Called when the UIKeyboardWillHideNotification is sent
|
||||
@@ -225,21 +228,23 @@ std::recursive_mutex lock_mutex;
|
||||
{
|
||||
CGRect frame = [[UIScreen mainScreen] bounds];
|
||||
self.view.frame = frame;
|
||||
[self async_lock];
|
||||
App::I.resize(frame.size.width * self.view.contentScaleFactor,
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->resize(frame.size.width * self.view.contentScaleFactor,
|
||||
frame.size.height * self.view.contentScaleFactor);
|
||||
App::I.animate = true;
|
||||
[self async_unlock];
|
||||
});
|
||||
App::I->animate = true;
|
||||
}
|
||||
|
||||
- (void)reset_touch
|
||||
{
|
||||
[self async_lock];
|
||||
if (t_count == 2)
|
||||
App::I.gesture_end();
|
||||
else
|
||||
App::I.mouse_cancel(0);
|
||||
[self async_unlock];
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
if (t_count == 2)
|
||||
App::I->gesture_end();
|
||||
else
|
||||
App::I->mouse_cancel(0);
|
||||
});
|
||||
t_count = 0;
|
||||
}
|
||||
|
||||
@@ -255,9 +260,8 @@ std::set<UITouch*> ignored_touch;
|
||||
if (source == kEventSource::Stylus)
|
||||
pen_down = true;
|
||||
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([touchLocation, scale, f=touch.force, source] {
|
||||
App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, f, source, 0);
|
||||
App::I->ui_task_async([touchLocation, scale, f=touch.force, source] {
|
||||
App::I->mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, f, source, 0);
|
||||
});
|
||||
t_count = 1;
|
||||
t_pos = {touchLocation.x * scale, touchLocation.y * scale};
|
||||
@@ -301,25 +305,23 @@ std::set<UITouch*> ignored_touch;
|
||||
|
||||
if (pen_down)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([tt0=t0.type,tt1=t1.type,p0,p1,f0=t0.force,f1=t1.force] {
|
||||
App::I->ui_task_async([tt0=t0.type,tt1=t1.type,p0,p1,f0=t0.force,f1=t1.force] {
|
||||
if (tt0 == UITouchType::UITouchTypeStylus)
|
||||
App::I.mouse_move(p0.x, p0.y, f0, kEventSource::Stylus, 0);
|
||||
App::I->mouse_move(p0.x, p0.y, f0, kEventSource::Stylus, 0);
|
||||
if (tt1 == UITouchType::UITouchTypeStylus)
|
||||
App::I.mouse_move(p1.x, p1.y, f1, kEventSource::Stylus, 0);
|
||||
App::I->mouse_move(p1.x, p1.y, f1, kEventSource::Stylus, 0);
|
||||
});
|
||||
}
|
||||
else if (n == 2)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([c=t_count, p0, p1] {
|
||||
App::I->ui_task_async([c=t_count, p0, p1] {
|
||||
if (c == 1)
|
||||
{
|
||||
App::I.mouse_cancel(0);
|
||||
App::I.gesture_start(p0, p1);
|
||||
App::I->mouse_cancel(0);
|
||||
App::I->gesture_start(p0, p1);
|
||||
}
|
||||
else
|
||||
App::I.gesture_move(p0, p1);
|
||||
App::I->gesture_move(p0, p1);
|
||||
});
|
||||
t_count = 2;
|
||||
}
|
||||
@@ -332,15 +334,14 @@ std::set<UITouch*> ignored_touch;
|
||||
//force = [app sonarpen_pressure];
|
||||
if (t_count == 2)
|
||||
{
|
||||
//App::I.gesture_end();
|
||||
//App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, force);
|
||||
//App::I->gesture_end();
|
||||
//App::I->mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, force);
|
||||
}
|
||||
else
|
||||
{
|
||||
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([touchLocation, scale, source, force] {
|
||||
App::I.mouse_move(touchLocation.x * scale, touchLocation.y * scale, force, source, 0);
|
||||
App::I->ui_task_async([touchLocation, scale, source, force] {
|
||||
App::I->mouse_move(touchLocation.x * scale, touchLocation.y * scale, force, source, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -361,12 +362,11 @@ std::set<UITouch*> ignored_touch;
|
||||
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
||||
pen_down = false;
|
||||
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([tc=t_count, touchLocation, scale, source] {
|
||||
App::I->ui_task_async([tc=t_count, touchLocation, scale, source] {
|
||||
if (tc == 2)
|
||||
App::I.gesture_end();
|
||||
App::I->gesture_end();
|
||||
else
|
||||
App::I.mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source, 0);
|
||||
App::I->mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source, 0);
|
||||
});
|
||||
|
||||
t_count = 0;
|
||||
@@ -375,15 +375,16 @@ std::set<UITouch*> ignored_touch;
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
||||
{
|
||||
[self async_lock];
|
||||
App::I.resize(size.width * self.view.contentScaleFactor,
|
||||
App::I->ui_task_async([=]
|
||||
{
|
||||
App::I->resize(size.width * self.view.contentScaleFactor,
|
||||
size.height * self.view.contentScaleFactor);
|
||||
[self async_unlock];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
App::I.redraw = true;
|
||||
App::I->redraw = true;
|
||||
[self resignFirstResponder];
|
||||
//[self registerForKeyboardNotifications];
|
||||
}
|
||||
@@ -391,8 +392,9 @@ std::set<UITouch*> ignored_touch;
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
App::I.initLog();
|
||||
App::I.ios_view = self;
|
||||
App::I = new App;
|
||||
App::I->initLog();
|
||||
App::I->ios_view = self;
|
||||
|
||||
//self.preferredFramesPerSecond = 60;
|
||||
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
|
||||
@@ -409,122 +411,17 @@ std::set<UITouch*> ignored_touch;
|
||||
view.enableSetNeedsDisplay = NO;
|
||||
glview = view;
|
||||
|
||||
App::I.width = view.frame.size.width * view.contentScaleFactor;
|
||||
App::I.height = view.frame.size.height * view.contentScaleFactor;
|
||||
App::I->width = view.frame.size.width * view.contentScaleFactor;
|
||||
App::I->height = view.frame.size.height * view.contentScaleFactor;
|
||||
|
||||
[self setupGL];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self tearDownGL];
|
||||
|
||||
if ([EAGLContext currentContext] == self.context) {
|
||||
[EAGLContext setCurrentContext:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
if ([self isViewLoaded] && ([[self view] window] == nil)) {
|
||||
self.view = nil;
|
||||
|
||||
[self tearDownGL];
|
||||
|
||||
if ([EAGLContext currentContext] == self.context) {
|
||||
[EAGLContext setCurrentContext:nil];
|
||||
}
|
||||
self.context = nil;
|
||||
}
|
||||
|
||||
// Dispose of any resources that can be recreated.
|
||||
App::I->render_thread_start();
|
||||
App::I->ui_thread_start();
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)tick
|
||||
{
|
||||
//std::lock_guard<std::mutex> lock(render_mutex);
|
||||
render_cv.notify_one();
|
||||
}
|
||||
|
||||
-(void)render_loop
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
static auto time = std::chrono::steady_clock::now();
|
||||
static double elapsed = 0;
|
||||
static double min_fps_timer = 0;
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto dt = std::chrono::duration<float>(now - time);
|
||||
time = now;
|
||||
elapsed += dt.count();
|
||||
min_fps_timer += dt.count();
|
||||
|
||||
if (min_fps_timer > 0.5)
|
||||
{
|
||||
App::I.redraw = true;
|
||||
min_fps_timer = 0;
|
||||
}
|
||||
|
||||
std::deque<std::packaged_task<void()>> working_list;
|
||||
if (!tasklist.empty())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
working_list = std::move(tasklist);
|
||||
}
|
||||
|
||||
App::I.tick(dt.count());
|
||||
|
||||
[self async_lock];
|
||||
if (!(App::I.redraw || App::I.animate || !working_list.empty()))
|
||||
{
|
||||
//[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
[self->glview display];
|
||||
[self async_unlock];
|
||||
std::unique_lock<std::mutex> lock(render_mutex);
|
||||
render_cv.wait(lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (!working_list.empty())
|
||||
{
|
||||
working_list.front()();
|
||||
working_list.pop_front();
|
||||
}
|
||||
App::I.clear();
|
||||
App::I.update(elapsed);
|
||||
[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
[self->glview display];
|
||||
[self async_unlock];
|
||||
elapsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupGL
|
||||
{
|
||||
[self async_lock];
|
||||
App::I.init();
|
||||
[self async_unlock];
|
||||
|
||||
std::thread([self]{
|
||||
[self render_loop];
|
||||
}).detach();
|
||||
|
||||
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick)];
|
||||
displayLink.frameInterval = 1;
|
||||
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)tearDownGL
|
||||
{
|
||||
[EAGLContext setCurrentContext:self.context];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GameView
|
||||
|
||||
@@ -520,6 +520,7 @@ void App::async_update()
|
||||
void App::async_redraw()
|
||||
{
|
||||
redraw = true;
|
||||
ui_cv.notify_all();
|
||||
}
|
||||
|
||||
void App::async_end()
|
||||
|
||||
@@ -34,7 +34,6 @@ NodeMessageBox* App::message_box(const std::string &title, const std::string& te
|
||||
m->btn_ok->m_text->set_text("Ok");
|
||||
if (!cancel_button)
|
||||
m->btn_cancel->destroy();
|
||||
layout[main_id]->update();
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
@@ -540,7 +540,6 @@ void App::init_menu_file()
|
||||
else
|
||||
{
|
||||
Image img;
|
||||
async_start();
|
||||
img.load_file(path);
|
||||
if (img.width == img.height / 6 || img.width == img.height * 2)
|
||||
{
|
||||
@@ -554,7 +553,6 @@ void App::init_menu_file()
|
||||
Canvas::set_mode(kCanvasMode::Import);
|
||||
}
|
||||
async_redraw();
|
||||
async_end();
|
||||
}
|
||||
});
|
||||
popup->mouse_release();
|
||||
|
||||
@@ -1448,6 +1448,7 @@ void Canvas::FloodData::apply()
|
||||
layer->m_dirty_face[plane] = true;
|
||||
layer->m_dirty_box[plane] = box_union(layer->m_dirty_box[plane], bb[plane]);
|
||||
}
|
||||
Canvas::I->m_unsaved = true;
|
||||
}
|
||||
|
||||
void Canvas::resize(int width, int height)
|
||||
|
||||
@@ -41,14 +41,9 @@
|
||||
|
||||
std::string base_address;
|
||||
std::atomic_flag handler_executed;
|
||||
void exception_handler(NSException *exception)
|
||||
|
||||
void save_recovery()
|
||||
{
|
||||
if (handler_executed.test_and_set())
|
||||
exit(0);
|
||||
LOG("exception %s\n", [[exception name] cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
||||
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
|
||||
auto t = std::time(nullptr);
|
||||
auto tm = *std::localtime(&t);
|
||||
std::ostringstream oss;
|
||||
@@ -57,6 +52,16 @@ void exception_handler(NSException *exception)
|
||||
|
||||
if (App::I->canvas && App::I->canvas->m_canvas)
|
||||
App::I->canvas->m_canvas->project_save_thread(path);
|
||||
}
|
||||
|
||||
void exception_handler(NSException *exception)
|
||||
{
|
||||
if (handler_executed.test_and_set())
|
||||
exit(0);
|
||||
LOG("exception %s\n", [[exception name] cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
||||
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
save_recovery();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -66,15 +71,19 @@ static void signal_handler (int signo) {
|
||||
LOG("signal %d\n", signo);
|
||||
NSString* callstack = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
||||
LOG("base:\n%s\ncallstack:\n%s", base_address.c_str(), [callstack cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
save_recovery();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
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";
|
||||
void SignalHandler(int sig, siginfo_t *info, void *context)
|
||||
{
|
||||
save_recovery();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (App::I->canvas && App::I->canvas->m_canvas)
|
||||
App::I->canvas->m_canvas->project_save_thread(path);
|
||||
void TerminateHandler()
|
||||
{
|
||||
save_recovery();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -89,4 +98,27 @@ void install_global_handlers()
|
||||
signal(SIGFPE, signal_handler);
|
||||
signal(SIGBUS, signal_handler);
|
||||
signal(SIGPIPE, signal_handler);
|
||||
|
||||
/*
|
||||
struct sigaction mySigAction;
|
||||
mySigAction.sa_sigaction = SignalHandler;
|
||||
mySigAction.sa_flags = SA_SIGINFO;
|
||||
|
||||
sigemptyset(&mySigAction.sa_mask);
|
||||
sigaction(SIGQUIT, &mySigAction, NULL);
|
||||
sigaction(SIGILL, &mySigAction, NULL);
|
||||
sigaction(SIGTRAP, &mySigAction, NULL);
|
||||
sigaction(SIGABRT, &mySigAction, NULL);
|
||||
sigaction(SIGEMT, &mySigAction, NULL);
|
||||
sigaction(SIGFPE, &mySigAction, NULL);
|
||||
sigaction(SIGBUS, &mySigAction, NULL);
|
||||
sigaction(SIGSEGV, &mySigAction, NULL);
|
||||
sigaction(SIGSYS, &mySigAction, NULL);
|
||||
sigaction(SIGPIPE, &mySigAction, NULL);
|
||||
sigaction(SIGALRM, &mySigAction, NULL);
|
||||
sigaction(SIGXCPU, &mySigAction, NULL);
|
||||
sigaction(SIGXFSZ, &mySigAction, NULL);
|
||||
|
||||
std::set_terminate(TerminateHandler);
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user