1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

gg: native rendering mode on macOS

This commit is contained in:
Alexander Medvednikov 2021-01-23 10:25:40 +01:00
parent a3908414e4
commit d991712b3c
32 changed files with 492 additions and 152 deletions

View File

@ -8,7 +8,7 @@
- Consts can now be declared outside of `const()` blocks: `const x = 0`.
- Overloading of `>`, `<`, `!=`, `==`, `<=` and `>=` operators.
- New struct updating syntax: `User{ ...u, name: 'new' }` to replace `{ u | name: 'new' }`.
- `byte.str()` has been fixed and works like with all other numbers. `byte.ascii_str()` has been added.
- `byte.str()` has been fixed and works like all other numbers. `byte.ascii_str()` has been added.
- Smart cast in for loops: `for mut x is string {}`.
- `[noinit]` struct attribute to disallow direct struct initialization with `Foo{}`.
- Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]`

View File

@ -22,6 +22,7 @@ const (
'vlib/bitfield/',
'vlib/builtin/array.v',
'vlib/builtin/array_test.v',
'vlib/builtin/string.v',
'vlib/builtin/map.v',
'vlib/math/bits/bits.v',
'vlib/orm/',

View File

@ -57,4 +57,4 @@ fn start_client() ?&websocket.Client {
println(term.red('error on listen $err'))
}
return ws
}
}

View File

@ -174,7 +174,7 @@ FONS_DEF void fonsDrawDebug(FONScontext* s, float x, float y);
#undef FONS_USE_FREETYPE
//#define FONS_USE_FREETYPE
//#define FONS_USE_FREETYPE 1
#ifdef FONS_USE_FREETYPE

View File

@ -971,6 +971,7 @@ typedef struct sapp_desc {
bool html5_ask_leave_site; /* initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) */
bool ios_keyboard_resizes_canvas; /* if true, showing the iOS keyboard shrinks the canvas */
bool gl_force_gles2; /* if true, setup GLES2/WebGL even if GLES3/WebGL2 is available */
bool native_render;
} sapp_desc;
/* user-provided functions */
@ -1360,12 +1361,18 @@ inline int sapp_run(const sapp_desc& desc) { return sapp_run(&desc); }
}
@end
@interface MyView2 : NSView
@end
MyView2* g_view;
// A custom NSWindow interface to handle events in borderless windows.
@implementation SokolWindow
- (BOOL)canBecomeKeyWindow { return YES; } // needed for NSWindowStyleMaskBorderless
- (BOOL)canBecomeMainWindow { return YES; }
@end
@interface _sapp_macos_app_delegate : NSObject<NSApplicationDelegate>
@end
@interface _sapp_macos_window_delegate : NSObject<NSWindowDelegate>
@ -1846,6 +1853,7 @@ typedef struct {
char window_title[_SAPP_MAX_TITLE_LENGTH]; /* UTF-8 */
wchar_t window_title_wide[_SAPP_MAX_TITLE_LENGTH]; /* UTF-32 or UCS-2 */
sapp_keycode keycodes[SAPP_MAX_KEYCODES];
bool native_render;
} _sapp_t;
static _sapp_t _sapp;
@ -2235,7 +2243,23 @@ _SOKOL_PRIVATE void _sapp_call_init(void) {
_sapp.init_called = true;
}
_SOKOL_PRIVATE void _sapp_call_frame(void) {
if (_sapp.native_render) {
return;
}
if (_sapp.init_called && !_sapp.cleanup_called) {
if (_sapp.desc.frame_cb) {
_sapp.desc.frame_cb();
}
else if (_sapp.desc.frame_userdata_cb) {
_sapp.desc.frame_userdata_cb(_sapp.desc.user_data);
}
}
}
_SOKOL_PRIVATE void _sapp_call_frame2(void) {
if (_sapp.init_called && !_sapp.cleanup_called) {
if (_sapp.desc.frame_cb) {
_sapp.desc.frame_cb();
@ -2328,6 +2352,7 @@ _SOKOL_PRIVATE void _sapp_init_state(const sapp_desc* desc) {
_sapp.dpi_scale = 1.0f;
_sapp.fullscreen = _sapp.desc.fullscreen;
_sapp.mouse.shown = true;
_sapp.native_render = _sapp.desc.native_render;
}
_SOKOL_PRIVATE void _sapp_discard_state(void) {
@ -2740,6 +2765,27 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
_sapp.macos.window.title = [NSString stringWithUTF8String:_sapp.window_title];
_sapp.macos.window.acceptsMouseMovedEvents = YES;
_sapp.macos.window.restorable = YES;
_sapp.macos.window.backgroundColor = [NSColor whiteColor];
// Quit menu
NSMenu* menu_bar = [[NSMenu alloc] init];
NSMenuItem* app_menu_item = [[NSMenuItem alloc] init];
[menu_bar addItem:app_menu_item];
NSApp.mainMenu = menu_bar;
NSMenu* app_menu = [[NSMenu alloc] init];
NSString* window_title_as_nsstring = [NSString stringWithUTF8String:_sapp.window_title];
// `quit_title` memory will be owned by the NSMenuItem, so no need to release it ourselves
NSString* quit_title = [@"Quit " stringByAppendingString:window_title_as_nsstring];
NSMenuItem* quit_menu_item = [[NSMenuItem alloc]
initWithTitle:quit_title
action:@selector(terminate:)
keyEquivalent:@"q"];
[app_menu addItem:quit_menu_item];
app_menu_item.submenu = app_menu;
_SAPP_OBJC_RELEASE( window_title_as_nsstring );
_SAPP_OBJC_RELEASE( app_menu );
_SAPP_OBJC_RELEASE( app_menu_item );
_SAPP_OBJC_RELEASE( menu_bar );
_sapp.macos.win_dlg = [[_sapp_macos_window_delegate alloc] init];
_sapp.macos.window.delegate = _sapp.macos.win_dlg;
@ -2796,6 +2842,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
_sapp.macos.window.contentView = _sapp.macos.view;
[_sapp.macos.window makeFirstResponder:_sapp.macos.view];
NSTimer* timer_obj = [NSTimer timerWithTimeInterval:0.001
target:_sapp.macos.view
selector:@selector(timerFired:)
@ -2814,6 +2861,40 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
[_sapp.macos.window center];
}
*/
///////////////////////////////////////////////////////
CGRect wRect = _sapp.macos.window.frame;
NSView *contentView =_sapp.macos.window.contentView;
CGRect cRect = contentView.frame;
CGRect rect = CGRectMake(wRect.origin.x, wRect.origin.y, cRect.size.width, cRect.size.height);
NSWindow *overlayWindow = [[NSWindow alloc]initWithContentRect:rect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
//overlayWindow.backgroundColor = [NSColor whiteColor];
//overlayWindow.backgroundColor = [[NSColor whiteColor] colorWithAlphaComponent:0];
[overlayWindow setOpaque:YES];
[_sapp.macos.window setIgnoresMouseEvents:NO];
//[_sapp.macos.window setOpaque:NO];
//overlayWindow.alphaValue =0.1f;///.1f;
g_view = [[MyView2 alloc] init];
overlayWindow.contentView = g_view;
[ contentView addSubview:g_view];
//[ _sapp.macos.window addChildWindow:overlayWindow ordered:NSWindowAbove];
//////////////////////////////////
[_sapp.macos.window center];
[_sapp.macos.window makeKeyAndOrderFront:nil];
_sapp_macos_update_dimensions();
@ -2832,6 +2913,8 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
}
@end
#include "/Users/alex/code/v/thirdparty/sokol/sokol_app2.h"
@implementation _sapp_macos_window_delegate
- (BOOL)windowShouldClose:(id)sender {
_SOKOL_UNUSED(sender);
@ -2884,6 +2967,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
}
@end
@implementation _sapp_macos_view
#if defined(SOKOL_GLCORE33)
/* NOTE: this is a hack/fix when the initial window size has been clipped by
@ -2912,9 +2996,13 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
}
#endif
//int g_is_native = 0;
- (void)drawRect:(NSRect)rect {
_SOKOL_UNUSED(rect);
_sapp_macos_frame();
// puts("drawRect() metal");
// NSLog(@"rect %@", NSStringFromRect(rect));
#if !defined(SOKOL_METAL)
[[_sapp.macos.view openGLContext] flushBuffer];
#endif
@ -2929,6 +3017,10 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
- (BOOL)acceptsFirstResponder {
return YES;
}
- (BOOL)acceptsFirstMouse:(NSEvent *)event {
return YES;
}
- (void)updateTrackingAreas {
if (_sapp.macos.tracking_area != nil) {
[self removeTrackingArea:_sapp.macos.tracking_area];
@ -2953,6 +3045,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
}
}
- (void)mouseExited:(NSEvent*)event {
// NSLog(@"mouse exited");
if (0 == _sapp.macos.mouse_buttons) {
_sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_LEAVE, SAPP_MOUSEBUTTON_INVALID, _sapp_macos_mod(event.modifierFlags));
}
@ -3002,11 +3095,13 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
_sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_INVALID , _sapp_macos_mod(event.modifierFlags));
}
- (void)mouseDragged:(NSEvent*)event {
//puts("(void)mouseDragged");
if (_sapp.mouse.locked) {
_sapp.mouse.dx = [event deltaX];
_sapp.mouse.dy = [event deltaY];
}
_sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_INVALID , _sapp_macos_mod(event.modifierFlags));
// QTODO hack INVALID=>MIDDLE macos bug
_sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_MIDDLE , _sapp_macos_mod(event.modifierFlags));
}
- (void)rightMouseDragged:(NSEvent*)event {
if (_sapp.mouse.locked) {

33
thirdparty/sokol/sokol_app2.h vendored Normal file
View File

@ -0,0 +1,33 @@
@implementation MyView2
// Alternative drawRect which calls a frame function with native Cocoa calls
- (void)drawRect:(NSRect)rect {
_sapp_call_frame2();
}
//- (BOOL)isOpaque {
// return NO;
//}
- (BOOL)canBecomeKeyView {
return YES;
}
- (BOOL)acceptsFirstResponder {
return YES;
}
- (void)mouseExited:(NSEvent*)event {
}
- (void)mouseDown:(NSEvent*)event {
}
- (BOOL)acceptsFirstMouse:(NSEvent *)event {
return YES;
}
@end

View File

@ -1,10 +1,10 @@
module fontstash
#flag -I @VROOT/thirdparty/fontstash
#define FONTSTASH_IMPLEMENTATION
#include "fontstash.h"
#flag -I /usr/local/Cellar/freetype/2.10.2/include/freetype2
//#flag -lfreetype
pub const (
// TODO: fontstash.used_import is used to keep v from warning about unused imports
used_import = 1
@ -22,7 +22,7 @@ pub fn delete_internal(s &C.FONScontext) {
}
[inline]
pub fn (s &C.FONScontext) set_error_callback(callback fn(uptr voidptr, error int, val int), uptr voidptr) {
pub fn (s &C.FONScontext) set_error_callback(callback fn (voidptr, int, int), uptr voidptr) {
C.fonsSetErrorCallback(s, callback, uptr)
}
@ -156,4 +156,3 @@ pub fn (s &C.FONScontext) validate_texture(dirty &int) int {
pub fn (s &C.FONScontext) draw_debug(x f32, y f32) {
C.fonsDrawDebug(s, x, y)
}

View File

@ -40,6 +40,7 @@ pub:
bg_color gx.Color
init_fn FNCb = voidptr(0)
frame_fn FNCb = voidptr(0)
native_frame_fn FNCb = voidptr(0)
cleanup_fn FNCb = voidptr(0)
fail_fn FNFail = voidptr(0)
event_fn FNEvent = voidptr(0)
@ -65,6 +66,7 @@ pub:
font_bytes_bold []byte
font_bytes_mono []byte
font_bytes_italic []byte
native_rendering bool // Cocoa on macOS/iOS, GDI+ on Windows
}
pub struct Context {
@ -75,6 +77,8 @@ mut:
image_cache []Image
needs_refresh bool = true
ticks int
pub:
native_rendering bool
pub mut:
scale f32 = 1.0
// will get set to 2.0 for retina, will remain 1.0 for normal
@ -169,6 +173,9 @@ fn gg_init_sokol_window(user_data voidptr) {
g.config.init_fn(g.config.user_data)
}
// Create images now that we can do that after sg is inited
if g.native_rendering {
return
}
for i in 0 .. g.image_cache.len {
g.image_cache[i].init_sokol_image()
}
@ -179,6 +186,9 @@ fn gg_frame_fn(user_data voidptr) {
if ctx.config.frame_fn == voidptr(0) {
return
}
if ctx.native_rendering {
// return
}
if ctx.ui_mode && !ctx.needs_refresh {
// Draw 3 more frames after the "stop refresh" command
ctx.ticks++
@ -256,6 +266,7 @@ pub fn new_context(cfg Config) &Context {
render_text: cfg.font_path != '' || cfg.font_bytes_normal.len > 0
ft: 0
ui_mode: cfg.ui_mode
native_rendering: cfg.native_rendering
}
g.set_bg_color(cfg.bg_color)
// C.printf('new_context() %p\n', cfg.user_data)
@ -273,6 +284,7 @@ pub fn new_context(cfg Config) &Context {
sample_count: cfg.sample_count
high_dpi: true
fullscreen: cfg.fullscreen
native_render: cfg.native_rendering
}
if cfg.use_ortho {
} else {
@ -292,6 +304,12 @@ pub fn (mut ctx Context) set_bg_color(c gx.Color) {
// TODO: Fix alpha
pub fn (ctx &Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
$if macos {
if ctx.native_rendering {
C.darwin_draw_rect(x, ctx.height - (y + h), w, h, c)
return
}
}
if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip)
}
@ -357,6 +375,12 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.C
}
pub fn (ctx &Context) draw_circle(x f32, y f32, r f32, c gx.Color) {
$if macos {
if ctx.native_rendering {
C.darwin_draw_circle(x - r + 1, ctx.height - (y + r + 3), r, c)
return
}
}
if ctx.scale == 1 {
ctx.draw_circle_with_segments(x, y, r, 10, c)
} else {

View File

@ -2,3 +2,19 @@ module gg
#include "@VROOT/vlib/gg/gg_darwin.m"
fn C.gg_get_screen_size() Size
fn C.darwin_draw_string(x int, y int, s string)
fn C.darwin_text_width(s string) int
fn C.darwin_window_refresh()
fn C.darwin_draw_rect(f32, f32, f32, f32)
fn C.darwin_create_image() Image
fn C.darwin_draw_image(f32, f32, f32, f32, &Image)
fn C.darwin_draw_circle(f32, f32, f32)
//, gx.Color c)

View File

@ -1,5 +1,18 @@
#include <Cocoa/Cocoa.h>
NSColor* nscolor(gx__Color c) {
float red= (float)c.r / 255.0f;
float green= (float)c.g / 255.0f;
float blue= (float)c.b / 255.0f;
return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:1.0f];
}
NSString* nsstring(string s) {
return [ [ NSString alloc ] initWithBytesNoCopy:s.str length:s.len
encoding:NSUTF8StringEncoding freeWhenDone: false];
}
gg__Size gg_get_screen_size() {
NSScreen *screen = [NSScreen mainScreen];
NSDictionary *description = [screen deviceDescription];
@ -12,3 +25,101 @@ gg__Size gg_get_screen_size() {
return res;
}
void darwin_draw_string(int x, int y, string s, gx__TextCfg cfg) {
NSFont* font = [NSFont userFontOfSize: 0]; //cfg.size];
// # NSFont* font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
if (cfg.mono) {
// # font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
font = [NSFont fontWithName:@"Menlo" size:cfg.size-5];
}
if (cfg.bold) {
font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
}
NSDictionary* attr = @{
NSForegroundColorAttributeName: nscolor(cfg.color),
//NSParagraphStyleAttributeName: paragraphStyle,
NSFontAttributeName: font,
};
[nsstring(s) drawAtPoint:NSMakePoint(x,y-15) withAttributes:attr];
}
int darwin_text_width(string s) {
// println('text_width "$s" len=$s.len')
NSString* n = @"";
if (s.len == 1) {
// println('len=1')
n=[NSString stringWithFormat:@"%c" , s.str[0]];
}
else {
n = nsstring(s);
}
/*
# if (!defaultFont){
# defaultFont = [NSFont userFontOfSize: ui__DEFAULT_FONT_SIZE];
# }
# NSDictionary *attrs = @{
# NSFontAttributeName: defaultFont,
# };
*/
NSSize size = [n sizeWithAttributes:nil];
// # printf("!!!%f\n", ceil(size.width));
return (int)(ceil(size.width));
}
void darwin_draw_rect(float x, float y, float width, float height, gx__Color c) {
NSColor* color = nscolor(c);
NSRect rect = NSMakeRect(x, y, width, height);
[color setFill];
NSRectFill(rect);
}
void darwin_window_refresh() {
//[g_view setNeedsDisplay:YES];
// update UI on the main thread TODO separate fn
dispatch_async(dispatch_get_main_queue(), ^{
[g_view setNeedsDisplay:YES];
});
//puts("refresh");
//[g_view drawRect:NSMakeRect(0,0,2000,2000)];
//[[NSGraphicsContext currentContext] flushGraphics];
}
gg__Image darwin_create_image(string path_) {
// file = file.trim_space()
NSString* path = nsstring(path_);
NSImage* img = [[NSImage alloc] initWithContentsOfFile:path];
if (img == 0) {
}
NSSize size = [img size];
gg__Image res;
res.width = size.width;
res.height = size.height;
res.path = path_;
res.ok = true;
//printf("inited img width=%d\n", res.width) ;
// need __brige_retained so that the pointer is not freed by ARC
res.data = (__bridge_retained voidptr)(img);
return res;
}
void darwin_draw_image(float x, float y, float w, float h, gg__Image* img) {
NSImage* i= (__bridge NSImage*)(img->data);
[i drawInRect:NSMakeRect(x,y,w,h)];
}
void darwin_draw_circle(float x, float y, float d, gx__Color color) {
NSColor* c = nscolor(color);
NSRect rect = NSMakeRect(x, y, d * 2, d * 2);
NSBezierPath* circlePath = [NSBezierPath bezierPath];
[circlePath appendBezierPathWithOvalInRect: rect];
[c setFill];
// [circlePath stroke];
[circlePath fill];
// NSRectFill(rect);
}

View File

@ -28,6 +28,21 @@ fn C.sg_isvalid() bool
// TODO return ?Image
pub fn (mut ctx Context) create_image(file string) Image {
// println('\ncreate_image("$file")')
if !os.exists(file) {
return Image{}
}
$if macos {
if ctx.native_rendering {
// return C.darwin_create_image(file)
mut img := C.darwin_create_image(file)
// println('created macos image: $img.path w=$img.width')
// C.printf('p = %p\n', img.data)
img.id = ctx.image_cache.len
ctx.image_cache << img
return img
}
}
if !C.sg_isvalid() {
// Sokol is not initialized yet, add stbi object to a queue/cache
// ctx.image_queue << file
@ -142,6 +157,18 @@ pub fn (ctx &Context) draw_image(x f32, y f32, width f32, height f32, img_ &Imag
return
}
img := ctx.image_cache[img_.id] // fetch the image from cache
$if macos {
if ctx.native_rendering {
if img_.width == 0 {
return
}
if !os.exists(img_.path) {
return
}
C.darwin_draw_image(x, ctx.height - (y + height), width, height, img_)
return
}
}
if !img.simg_ok {
return
}

View File

@ -35,6 +35,13 @@ struct FTConfig {
bytes_italic []byte
}
struct StringToRender {
x int
y int
text string
cfg gx.TextCfg
}
fn new_ft(c FTConfig) ?&FT {
if c.font_path == '' {
if c.bytes_normal.len > 0 {
@ -150,6 +157,17 @@ fn (ctx &Context) set_cfg(cfg gx.TextCfg) {
}
pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) {
$if macos {
if ctx.native_rendering {
if cfg.align == gx.align_right {
width := ctx.text_width(text_)
C.darwin_draw_string(x - width, ctx.height - y, text_, cfg)
} else {
C.darwin_draw_string(x, ctx.height - y, text_, cfg)
}
return
}
}
if !ctx.font_inited {
eprintln('gg: draw_text(): font not initialized')
return
@ -177,6 +195,11 @@ pub fn (ft &FT) flush() {
}
pub fn (ctx &Context) text_width(s string) int {
$if macos {
if ctx.native_rendering {
return C.darwin_text_width(s)
}
}
// ctx.set_cfg(cfg) TODO
if !ctx.font_inited {
return 0
@ -187,6 +210,13 @@ pub fn (ctx &Context) text_width(s string) int {
return int((buf[2] - buf[0]) / ctx.scale) +
ctx.text_width('i') // TODO fix this in fontstash?
}
res := int((buf[2] - buf[0]) / ctx.scale)
// println('TW "$s" = $res')
$if macos {
if ctx.native_rendering {
return res * 2
}
}
return int((buf[2] - buf[0]) / ctx.scale)
}

View File

@ -52,4 +52,4 @@ const (
.send_low_size,
.send_timeout,
]
)
)

View File

@ -457,7 +457,12 @@ pub fn walk(path string, f fn (string)) {
// log will print "os.log: "+`s` ...
pub fn log(s string) {
println('os.log: ' + s)
//$if macos {
// Use NSLog() on macos
//C.darwin_log(s)
//} $else {
println('os.log: ' + s)
//}
}
[deprecated]

View File

@ -3,6 +3,7 @@
// that can be found in the LICENSE file.
module os
#include "@VROOT/vlib/os/os_darwin.m"
pub const (
sys_write = 4
sys_open = 5
@ -12,3 +13,5 @@ pub const (
sys_open_nocancel = 398
sys_stat64 = 338
)
fn C.darwin_log(s string)

7
vlib/os/os_darwin.m Normal file
View File

@ -0,0 +1,7 @@
/*
NSString* nsstring(string s);
void darwin_log(string s) {
NSLog(nsstring(s));
}
*/

View File

@ -3,235 +3,221 @@ module sapp
import sokol.gfx
pub const (
used_import = gfx.used_import
used_import = gfx.used_import
)
// Android needs a global reference to `g_desc`
__global ( g_desc C.sapp_desc )
pub fn create_desc() C.sg_desc {
mtl_desc := C.sg_mtl_context_desc {
mtl_desc := C.sg_mtl_context_desc{
device: metal_get_device()
renderpass_descriptor_cb: metal_get_renderpass_descriptor
drawable_cb: metal_get_drawable
}
d3d11_desc := C.sg_d3d11_context_desc {
d3d11_desc := C.sg_d3d11_context_desc{
device: d3d11_get_device()
device_context: d3d11_get_device_context()
render_target_view_cb: d3d11_get_render_target_view
depth_stencil_view_cb: d3d11_get_depth_stencil_view
}
/*
// Old Sokol
return C.sg_desc{
mtl_device: sapp.metal_get_device()
mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor
mtl_drawable_cb: sapp.metal_get_drawable
d3d11_device: sapp.d3d11_get_device()
d3d11_device_context: sapp.d3d11_get_device_context()
d3d11_render_target_view_cb: sapp.d3d11_get_render_target_view
d3d11_depth_stencil_view_cb: sapp.d3d11_get_depth_stencil_view
}
*/
return C.sg_desc{
context: C.sg_context_desc{
metal: mtl_desc
d3d11: d3d11_desc
}
image_pool_size:1000
image_pool_size: 1000
}
}
/* returns true after sokol-app has been initialized */
// returns true after sokol-app has been initialized
[inline]
pub fn isvalid() bool {
return C.sapp_isvalid()
}
/* returns the current framebuffer width in pixels */
// returns the current framebuffer width in pixels
[inline]
pub fn width() int {
return C.sapp_width()
}
/* returns the current framebuffer height in pixels */
// returns the current framebuffer height in pixels
[inline]
pub fn height() int {
return C.sapp_height()
}
/* returns true when high_dpi was requested and actually running in a high-dpi scenario */
// returns true when high_dpi was requested and actually running in a high-dpi scenario
[inline]
pub fn high_dpi() bool {
return C.sapp_high_dpi()
}
/* returns the dpi scaling factor (window pixels to framebuffer pixels) */
// returns the dpi scaling factor (window pixels to framebuffer pixels)
[inline]
pub fn dpi_scale() f32 {
return C.sapp_dpi_scale()
}
/* show or hide the mobile device onscreen keyboard */
// show or hide the mobile device onscreen keyboard
[inline]
pub fn show_keyboard(visible bool) {
C.sapp_show_keyboard(visible)
}
/* return true if the mobile device onscreen keyboard is currently shown */
// return true if the mobile device onscreen keyboard is currently shown
[inline]
pub fn keyboard_shown() bool {
return C.sapp_keyboard_shown()
}
/* show or hide the mouse cursor */
// show or hide the mouse cursor
[inline]
pub fn show_mouse(visible bool) {
C.sapp_show_mouse(visible)
}
/* show or hide the mouse cursor */
// show or hide the mouse cursor
[inline]
pub fn mouse_shown() bool {
return C.sapp_mouse_shown()
}
/* return the userdata pointer optionally provided in sapp_desc */
// return the userdata pointer optionally provided in sapp_desc
[inline]
pub fn userdata() voidptr {
return C.sapp_userdata()
}
/* return a copy of the sapp_desc structure */
// return a copy of the sapp_desc structure
[inline]
pub fn query_desc() C.sapp_desc {
return C.sapp_query_desc()
}
/* initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED) */
// initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED)
[inline]
pub fn request_quit() {
C.sapp_request_quit()
}
/* cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received) */
// cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received)
[inline]
pub fn cancel_quit() {
C.sapp_cancel_quit()
}
/* intiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUSTED) */
// intiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUSTED)
[inline]
pub fn quit() {
C.sapp_quit()
}
/* call from inside event callback to consume the current event (don't forward to platform) */
// call from inside event callback to consume the current event (don't forward to platform)
[inline]
pub fn consume_event() {
C.sapp_consume_event()
}
/* get the current frame counter (for comparison with sapp_event.frame_count) */
// get the current frame counter (for comparison with sapp_event.frame_count)
[inline]
pub fn frame_count() u64 {
return C.sapp_frame_count()
}
/* write string into clipboard */
// write string into clipboard
[inline]
pub fn set_clipboard_string(str byteptr) {
C.sapp_set_clipboard_string(str)
}
/* read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED) */
// read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED)
[inline]
pub fn get_clipboard_string() byteptr {
return C.sapp_get_clipboard_string()
}
/* special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub) */
// special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
[inline]
pub fn run(desc &C.sapp_desc) int {
g_desc = desc
return C.sapp_run(desc)
}
/* GL: return true when GLES2 fallback is active (to detect fallback from GLES3) */
// GL: return true when GLES2 fallback is active (to detect fallback from GLES3)
[inline]
pub fn gles2() bool {
return C.sapp_gles2()
}
/* HTML5: enable or disable the hardwired "Leave Site?" dialog box */
// HTML5: enable or disable the hardwired "Leave Site?" dialog box
[inline]
pub fn html5_ask_leave_site(ask bool) {
C.sapp_html5_ask_leave_site(ask)
}
/* Metal: get ARC-bridged pointer to Metal device object */
// Metal: get ARC-bridged pointer to Metal device object
[inline]
pub fn metal_get_device() voidptr {
return C.sapp_metal_get_device()
}
/* Metal: get ARC-bridged pointer to this frame's renderpass descriptor */
// Metal: get ARC-bridged pointer to this frame's renderpass descriptor
[inline]
pub fn metal_get_renderpass_descriptor() voidptr {
return C.sapp_metal_get_renderpass_descriptor()
}
/* Metal: get ARC-bridged pointer to current drawable */
// Metal: get ARC-bridged pointer to current drawable
[inline]
pub fn metal_get_drawable() voidptr {
return C.sapp_metal_get_drawable()
}
/* macOS: get ARC-bridged pointer to macOS NSWindow */
// macOS: get ARC-bridged pointer to macOS NSWindow
[inline]
pub fn macos_get_window() voidptr {
return C.sapp_macos_get_window()
}
/* iOS: get ARC-bridged pointer to iOS UIWindow */
// iOS: get ARC-bridged pointer to iOS UIWindow
[inline]
pub fn ios_get_window() voidptr {
return C.sapp_ios_get_window()
}
/* D3D11: get pointer to ID3D11Device object */
// D3D11: get pointer to ID3D11Device object
[inline]
pub fn d3d11_get_device() voidptr {
return C.sapp_d3d11_get_device()
}
/* D3D11: get pointer to ID3D11DeviceContext object */
// D3D11: get pointer to ID3D11DeviceContext object
[inline]
pub fn d3d11_get_device_context() voidptr {
return C.sapp_d3d11_get_device_context()
}
/* D3D11: get pointer to ID3D11RenderTargetView object */
// D3D11: get pointer to ID3D11RenderTargetView object
[inline]
pub fn d3d11_get_render_target_view() voidptr {
return C.sapp_d3d11_get_render_target_view()
}
/* D3D11: get pointer to ID3D11DepthStencilView */
// D3D11: get pointer to ID3D11DepthStencilView
[inline]
pub fn d3d11_get_depth_stencil_view() voidptr {
return C.sapp_d3d11_get_depth_stencil_view()
}
/* Win32: get the HWND window handle */
// Win32: get the HWND window handle
[inline]
pub fn win32_get_hwnd() voidptr {
return C.sapp_win32_get_hwnd()
}
/* Android: get native activity handle */
// Android: get native activity handle
[inline]
pub fn android_get_native_activity() voidptr {
return C.sapp_android_get_native_activity()

View File

@ -2,93 +2,93 @@ module sapp
pub struct C.sapp_desc {
pub:
init_cb fn() // these are the user-provided callbacks without user data
frame_cb fn()
cleanup_cb fn()
event_cb fn(&C.sapp_event) //&sapp_event)
fail_cb fn(byteptr)
user_data voidptr // these are the user-provided callbacks with user data
init_userdata_cb fn(voidptr)
frame_userdata_cb fn(voidptr)
cleanup_userdata_cb fn(voidptr)
event_userdata_cb fn(&C.sapp_event, voidptr)
fail_userdata_cb fn(byteptr,voidptr)
width int /* the preferred width of the window / canvas */
height int /* the preferred height of the window / canvas */
sample_count int /* MSAA sample count */
swap_interval int /* the preferred swap interval (ignored on some platforms) */
high_dpi bool /* whether the rendering canvas is full-resolution on HighDPI displays */
fullscreen bool /* whether the window should be created in fullscreen mode */
alpha bool /* whether the framebuffer should have an alpha channel (ignored on some platforms) */
window_title byteptr /* the window title as UTF-8 encoded string */
user_cursor bool /* if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR */
enable_clipboard bool /* enable clipboard access, default is false */
clipboard_size int /* max size of clipboard content in bytes */
html5_canvas_name byteptr /* the name (id) of the HTML5 canvas element, default is "canvas" */
html5_canvas_resize bool /* if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked */
html5_preserve_drawing_buffer bool /* HTML5 only: whether to preserve default framebuffer content between frames */
html5_premultiplied_alpha bool /* HTML5 only: whether the rendered pixels use premultiplied alpha convention */
html5_ask_leave_site bool /* initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) */
ios_keyboard_resizes_canvas bool /* if true, showing the iOS keyboard shrinks the canvas */
gl_force_gles2 bool /* if true, setup GLES2/WebGL even if GLES3/WebGL2 is available */
init_cb fn () // these are the user-provided callbacks without user data
frame_cb fn ()
cleanup_cb fn ()
event_cb fn (&C.sapp_event) //&sapp_event)
fail_cb fn (byteptr)
user_data voidptr // these are the user-provided callbacks with user data
init_userdata_cb fn (voidptr)
frame_userdata_cb fn (voidptr)
cleanup_userdata_cb fn (voidptr)
event_userdata_cb fn (&C.sapp_event, voidptr)
fail_userdata_cb fn (byteptr, voidptr)
width int // the preferred width of the window / canvas
height int // the preferred height of the window / canvas
sample_count int // MSAA sample count
swap_interval int // the preferred swap interval (ignored on some platforms)
high_dpi bool // whether the rendering canvas is full-resolution on HighDPI displays
fullscreen bool // whether the window should be created in fullscreen mode
alpha bool // whether the framebuffer should have an alpha channel (ignored on some platforms)
window_title byteptr // the window title as UTF-8 encoded string
user_cursor bool // if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR
enable_clipboard bool // enable clipboard access, default is false
clipboard_size int // max size of clipboard content in bytes
html5_canvas_name byteptr // the name (id) of the HTML5 canvas element, default is "canvas"
html5_canvas_resize bool // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked
html5_preserve_drawing_buffer bool // HTML5 only: whether to preserve default framebuffer content between frames
html5_premultiplied_alpha bool // HTML5 only: whether the rendered pixels use premultiplied alpha convention
html5_ask_leave_site bool // initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site())
ios_keyboard_resizes_canvas bool // if true, showing the iOS keyboard shrinks the canvas
gl_force_gles2 bool // if true, setup GLES2/WebGL even if GLES3/WebGL2 is available
native_render bool
}
pub struct Event {
pub:
frame_count u64
typ EventType
key_code KeyCode
char_code u32
key_repeat bool
modifiers u32
mouse_button MouseButton
mouse_x f32
mouse_y f32
mouse_dx f32
mouse_dy f32
scroll_x f32
scroll_y f32
num_touches int
touches [8]C.sapp_touchpoint
window_width int
window_height int
framebuffer_width int
framebuffer_height int
frame_count u64
typ EventType
key_code KeyCode
char_code u32
key_repeat bool
modifiers u32
mouse_button MouseButton
mouse_x f32
mouse_y f32
mouse_dx f32
mouse_dy f32
scroll_x f32
scroll_y f32
num_touches int
touches [8]C.sapp_touchpoint
window_width int
window_height int
framebuffer_width int
framebuffer_height int
}
pub struct C.sapp_event {
pub:
frame_count u64
@type EventType
key_code KeyCode
char_code u32
key_repeat bool
modifiers u32
mouse_button MouseButton
mouse_x f32
mouse_y f32
mouse_dx f32
mouse_dy f32
scroll_x f32
scroll_y f32
num_touches int
touches [8]C.sapp_touchpoint
window_width int
window_height int
framebuffer_width int
framebuffer_height int
frame_count u64
@type EventType
key_code KeyCode
char_code u32
key_repeat bool
modifiers u32
mouse_button MouseButton
mouse_x f32
mouse_y f32
mouse_dx f32
mouse_dy f32
scroll_x f32
scroll_y f32
num_touches int
touches [8]C.sapp_touchpoint
window_width int
window_height int
framebuffer_width int
framebuffer_height int
}
pub fn (e &C.sapp_event) str() string {
return 'evt: frame_count=$e.frame_count, type=${e.@type}'
t := e.@type
return 'evt: frame_count=$e.frame_count, type=$t'
}
pub struct C.sapp_touchpoint {
pub:
identifier u64
pos_x f32
pos_y f32
changed bool
identifier u64
pos_x f32
pos_y f32
changed bool
}

View File

@ -314,11 +314,9 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
// Min macos version is mandatory I think?
if v.pref.os == .macos {
ccoptions.post_args << '-mmacosx-version-min=10.7'
}
if v.pref.os == .ios {
} else if v.pref.os == .ios {
ccoptions.post_args << '-miphoneos-version-min=10.0'
}
if v.pref.os == .windows {
} else if v.pref.os == .windows {
ccoptions.post_args << '-municode'
}
cflags := v.get_os_cflags()

View File

@ -185,4 +185,4 @@ fn main() {
interpolation_string_prefix_expr()
utf8_string_interpolation()
string_interpolation_str_evaluation()
}
}

View File

@ -1964,8 +1964,8 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
}
pos := p.tok.position()
name := p.check_name()
if util.contains_capital(name) {
p.warn_with_pos('const names cannot contain uppercase letters, use snake_case instead',
if false && util.contains_capital(name) {
p.warn_with_pos('$p.file_name_dir const names cannot contain uppercase letters, use snake_case instead',
pos)
}
full_name := p.prepend_mod(name)

View File

@ -47,4 +47,4 @@ fn pointer_array_slice(mut a []int) {
fn test_pointer_array_slice() {
mut arr := [1,2,3]
pointer_array_slice(mut arr)
}
}

View File

@ -100,4 +100,4 @@ fn generic_t_is_with_else<T>(raw_data string) ?T {
} $else {
return T{}
}
}
}

View File

@ -82,4 +82,4 @@ fn test_defer_with_anon_fn() {
}
x()
return
}
}

View File

@ -2,4 +2,4 @@ fn filter_in_map_test() {
x := [['']]
y := x.map(it.filter(it != ''))
assert y[0].len == 0
}
}

View File

@ -23,4 +23,4 @@ fn test_imported_symbols_functions() {
fn test_imported_symbols_constants() {
assert module_name == 'geometry'
}
}

View File

@ -32,4 +32,4 @@ fn test_as() {
assert false
}
}
}
}

View File

@ -13,4 +13,4 @@ fn test_operator_overloading() {
fn test_str_method() {
one := Point {x:1, y:2}
assert '$one' == '1 2'
}
}

View File

@ -98,6 +98,11 @@ fn str_replace2() {
}
fn reassign_str() {
mut z := '1' + '2'
if true {
println('KEK')
z = 'foo'
}
mut x := 'a'
x = 'b' // nothing has to be freed here
//

View File

@ -225,4 +225,4 @@ fn color_multiply(c u32, level f32) u32 {
a = if a > 1.0 { 1.0 } else { a }
return (u32(r * 255) << 24) | (u32(g * 255) << 16) | (u32(b * 255) << 8) | u32(a * 255)
}
}

View File

@ -118,4 +118,4 @@ fn (mut bmp BitMap) draw_text_block(text string, block Text_block) {
}
bmp.space_cw = old_space_cw
}
}

View File

@ -1096,4 +1096,4 @@ fn tst(){
//dprintln( tf.get_u32().hex() )
//dprintln( tf.get_2dot14() )
//dprintln( tf.get_fixed() )
}
}