<commit_before>#ifndef EBITEN_GRAPHICS_DETAIL_OPENGL_MACOSX_NATIVE_VIEW_MM
#define EBITEN_GRAPHICS_DETAIL_OPENGL_MACOSX_NATIVE_VIEW_MM

/*
 * Reference:
 *   http://developer.apple.com/library/mac/#qa/qa1385/_index.html
 *   http://www.alecjacobson.com/weblog/?p=2185
 */

// TODO: Use NSViewController?

#include "ebiten/input.hpp"
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#include <functional>

@interface EbitenOpenGLView : NSOpenGLView {
@private
  CVDisplayLinkRef displayLink_;
  std::function<bool()> updatingFunc_;
  ebiten::input* input_;
}

- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime;
- (void)setUpdatingFunc:(std::function<bool()> const&)updatingFunc;

@end

static CVReturn
EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
                          CVTimeStamp const* now,
                          CVTimeStamp const* outputTime,
                          CVOptionFlags flagsIn,
                          CVOptionFlags* flagsOut,
                          void* displayLinkContext) {
  (void)displayLink;
  (void)now;
  (void)flagsIn;
  (void)flagsOut;
  @autoreleasepool {
    EbitenOpenGLView* view = (__bridge EbitenOpenGLView*)displayLinkContext;
    return [view getFrameForTime:outputTime];
  }
}

#ifndef EBITEN_WITHOUT_OBJC_IMPL
@implementation EbitenOpenGLView

- (void)dealloc {
  ::CVDisplayLinkRelease(self->displayLink_);
  // Do not call [super dealloc] because of ARC.
}

- (void)prepareOpenGL {
  [super prepareOpenGL];
  NSOpenGLContext* openGLContext = [self openGLContext];
  assert(openGLContext != nil);
  GLint const swapInterval = 1;
  [openGLContext setValues:&swapInterval
              forParameter:NSOpenGLCPSwapInterval]; 
  ::CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink_);
  ::CVDisplayLinkSetOutputCallback(self->displayLink_,
                                   &EbitenDisplayLinkCallback,
                                   (__bridge void*)self);
  CGLContextObj cglContext = (CGLContextObj)[openGLContext CGLContextObj];
  CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[[self pixelFormat] CGLPixelFormatObj];
  ::CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink_,
                                                      cglContext,
                                                      cglPixelFormat);
  ::CVDisplayLinkStart(self->displayLink_);
}

- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime {
  (void)outputTime;
  if (!self->updatingFunc_) {
    return kCVReturnSuccess;;
  }
  NSOpenGLContext* context = [self openGLContext];
  assert(context != nil);
  [context makeCurrentContext];
  bool terminated = false;
  {
    ::CGLLockContext((CGLContextObj)[context CGLContextObj]);
    terminated = self->updatingFunc_();
    [context flushBuffer];
    ::CGLUnlockContext((CGLContextObj)[context CGLContextObj]);
  }
  if (terminated) {
    ::CVDisplayLinkStop(self->displayLink_);
    return kCVReturnSuccess;;<commit_msg>Removed CVDisplayLinkStop<commit_after>#ifndef EBITEN_GRAPHICS_DETAIL_OPENGL_MACOSX_NATIVE_VIEW_MM
#define EBITEN_GRAPHICS_DETAIL_OPENGL_MACOSX_NATIVE_VIEW_MM

/*
 * Reference:
 *   http://developer.apple.com/library/mac/#qa/qa1385/_index.html
 *   http://www.alecjacobson.com/weblog/?p=2185
 */

// TODO: Use NSViewController?

#include "ebiten/input.hpp"
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#include <functional>

@interface EbitenOpenGLView : NSOpenGLView {
@private
  CVDisplayLinkRef displayLink_;
  std::function<bool()> updatingFunc_;
  ebiten::input* input_;
}

- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime;
- (void)setUpdatingFunc:(std::function<bool()> const&)updatingFunc;

@end

static CVReturn
EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
                          CVTimeStamp const* now,
                          CVTimeStamp const* outputTime,
                          CVOptionFlags flagsIn,
                          CVOptionFlags* flagsOut,
                          void* displayLinkContext) {
  (void)displayLink;
  (void)now;
  (void)flagsIn;
  (void)flagsOut;
  @autoreleasepool {
    EbitenOpenGLView* view = (__bridge EbitenOpenGLView*)displayLinkContext;
    return [view getFrameForTime:outputTime];
  }
}

#ifndef EBITEN_WITHOUT_OBJC_IMPL
@implementation EbitenOpenGLView

- (void)dealloc {
  ::CVDisplayLinkRelease(self->displayLink_);
  // Do not call [super dealloc] because of ARC.
}

- (void)prepareOpenGL {
  [super prepareOpenGL];
  NSOpenGLContext* openGLContext = [self openGLContext];
  assert(openGLContext != nil);
  GLint const swapInterval = 1;
  [openGLContext setValues:&swapInterval
              forParameter:NSOpenGLCPSwapInterval]; 
  ::CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink_);
  ::CVDisplayLinkSetOutputCallback(self->displayLink_,
                                   &EbitenDisplayLinkCallback,
                                   (__bridge void*)self);
  CGLContextObj cglContext = (CGLContextObj)[openGLContext CGLContextObj];
  CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[[self pixelFormat] CGLPixelFormatObj];
  ::CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink_,
                                                      cglContext,
                                                      cglPixelFormat);
  ::CVDisplayLinkStart(self->displayLink_);
}

- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime {
  (void)outputTime;
  if (!self->updatingFunc_) {
    return kCVReturnSuccess;;
  }
  NSOpenGLContext* context = [self openGLContext];
  assert(context != nil);
  [context makeCurrentContext];
  bool terminated = false;
  {
    ::CGLLockContext((CGLContextObj)[context CGLContextObj]);
    terminated = self->updatingFunc_();
    [context flushBuffer];
    ::CGLUnlockContext((CGLContextObj)[context CGLContextObj]);
  }
  if (terminated) {
    // It may cause problems when closing the window.
    // TODO: Move it?
    //::CVDisplayLinkStop(self->displayLink_);
    return kCVReturnSuccess;
{'fraction_non_alphanumeric': 0.10310992848827541, 'fraction_numerical': 0.002993514052885415, 'mean_word_length': 3.4416543574593796, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2889816', 'n_tokens_mistral': 1901, 'n_tokens_neox': 1836, 'n_words': 291}