Browse Source

Fix multithread allocation crash caused by using static variables.

Sam Jaffe 6 years ago
parent
commit
91305c9979
2 changed files with 25 additions and 20 deletions
  1. 4 4
      danmaku/Base.lproj/MainMenu.xib
  2. 21 16
      danmaku/GameView.mm

+ 4 - 4
danmaku/Base.lproj/MainMenu.xib

@@ -671,14 +671,14 @@
         <window title="DanmakuRPG" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="GameWindow">
             <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
-            <rect key="contentRect" x="0.0" y="0.0" width="1200" height="700"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
+            <rect key="contentRect" x="0.0" y="0.0" width="1400" height="800"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1400" height="800"/>
             <view key="contentView" id="EiT-Mj-1SZ">
-                <rect key="frame" x="0.0" y="0.0" width="1200" height="700"/>
+                <rect key="frame" x="0.0" y="0.0" width="1400" height="800"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
                     <openGLView fixedFrame="YES" useAuxiliaryDepthBufferStencil="NO" useDoubleBufferingEnabled="YES" allowOffline="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9rQ-QQ-4fS" customClass="GameView">
-                        <rect key="frame" x="0.0" y="0.0" width="1200" height="700"/>
+                        <rect key="frame" x="0.0" y="0.0" width="1400" height="800"/>
                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
                     </openGLView>
                 </subviews>

+ 21 - 16
danmaku/GameView.mm

@@ -19,10 +19,15 @@
 namespace env { namespace detail {
   extern void resize_screen(math::vec2i const&);
 }}
-static std::shared_ptr<graphics::direct_renderer> renderer;
-static std::shared_ptr<engine::game_dispatch> game;
 
-@implementation GameView
+@implementation GameView {
+  std::shared_ptr<graphics::direct_renderer> renderer;
+  std::shared_ptr<engine::game_dispatch> game;
+};
+
+- (id)initWithCoder:(NSCoder *)decoder {
+  return self = [super initWithCoder:decoder];
+}
 
 - (id)initWithFrame:(NSRect)aRect {
   NSOpenGLPixelFormatAttribute attr[] = {
@@ -41,6 +46,14 @@ static std::shared_ptr<engine::game_dispatch> game;
     return nil;
   }
 
+  using graphics::direct_renderer;
+  using graphics::driver;
+  renderer = std::make_shared<direct_renderer>(driver::openGL);
+  game = std::make_shared<engine::game_dispatch>(renderer);
+  auto world = danmaku::world::load_world("scripts/level/world.json", game);
+  game->register_scene(world);
+  game->activate_scene("light-1");
+
   // make the context current
   NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:nsglFormat
                                                         shareContext:nil];
@@ -52,16 +65,6 @@ static std::shared_ptr<engine::game_dispatch> game;
 }
 
 - (void)prepareOpenGL {
-  using graphics::direct_renderer;
-  using graphics::driver;
-  renderer = std::make_shared<direct_renderer>(driver::openGL);
-  game = std::make_shared<engine::game_dispatch>(renderer);
-  auto world = danmaku::world::load_world("scripts/level/world.json", game);
-  game->register_scene(world);
-  game->activate_scene("light-1");
-  
-  renderer->clear();
-  
   // enable vertical sychronization to refresh rate
   const GLint vals = 0x01;
   [[self openGLContext] setValues:&vals forParameter:NSOpenGLCPSwapInterval];
@@ -77,8 +80,10 @@ static std::shared_ptr<engine::game_dispatch> game;
   
   env::detail::resize_screen({{(int)dirtyRect.size.width,
                                (int)dirtyRect.size.height}});
-  renderer->clear();
-  game->render();
+  if (game) {
+    renderer->clear();
+    game->render();
+  }
   //  glFlush();
   // the correct way to do double buffering on Mac is this:
   [[self openGLContext] flushBuffer];
@@ -189,7 +194,7 @@ static NSTimeInterval const FRAME_INTERVAL = 1.0 / 60.0;
 
 - (void)windowDidBecomeMain:(NSNotification *)notification {
   NSLog(@"window did become main");
-  
+
   // env::resume_clock();
   [self setNeedsDisplay:YES];