Refactor windows and web compiling
This commit is contained in:
26
build.bat
26
build.bat
@@ -3,27 +3,13 @@
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
if "%1"=="release" (
|
||||
set profile_flags=-DDEBUG_BUILD=0 -O2
|
||||
) else (
|
||||
set profile_flags=-DDEBUG_BUILD=1
|
||||
)
|
||||
set flags=/EHsc- /MD /Zi /FC /nologo /WX /W3 /wd4200 /wd4334 /diagnostics:column -DDEBUG_BUILD=1
|
||||
|
||||
if not exist "luaunity.obj" (
|
||||
cl -Zi -nologo -I../src/external/lua/src -I../src/external/glad ../src/external/luaunity.c ../src/external/glad/glad.c -c
|
||||
)
|
||||
|
||||
cl /WX /W3 /wd4200 /diagnostics:column -FC -Zi -nologo -Fe:metaprogram.exe -I../src ../src/metaprogram/metaprogram.cpp
|
||||
cl %flags% -Fe:metaprogram.exe -I../src ../src/metaprogram/metaprogram.cpp
|
||||
metaprogram.exe
|
||||
|
||||
set libs=../src/external/SDL/win32-static/SDL3-static.lib ../src/external/SDL/win32-static/SDL_uclibc.lib kernel32.lib gdi32.lib user32.lib Imm32.lib ole32.lib Shell32.lib OleAut32.lib Cfgmgr32.lib Setupapi.lib Advapi32.lib version.lib winmm.lib
|
||||
cl %flags% ../src/text_editor/text_editor.cpp -Fe:te.exe -I../src/external/SDL/include -I../src/external/lua/src -I../src/external/glad -I../src/ %libs% -link /SUBSYSTEM:WINDOWS /NODEFAULTLIB:LIBCMT /NODEFAULTLIB:MSVCRTD
|
||||
|
||||
rem set sdl=../src/external/SDL/win32-static/SDL3-static.lib ../src/external/SDL/win32-static/SDL_uclibc.lib
|
||||
rem cl /EHsc- /MD /Zi /FC /nologo /WX /W3 /wd4200 /diagnostics:column %profile_flags% ../src/text_editor/text_editor.cpp ../src/basic/win32.cpp -Fe:te.exe -I../src/external/SDL/include -I../src/external/lua/src -I../src/external/glad -I../src/ luaunity.obj glad.obj kernel32.lib gdi32.lib user32.lib Imm32.lib ole32.lib Shell32.lib OleAut32.lib Cfgmgr32.lib Setupapi.lib Advapi32.lib version.lib winmm.lib %sdl% -link /SUBSYSTEM:WINDOWS /NODEFAULTLIB:LIBCMT /NODEFAULTLIB:MSVCRTD
|
||||
|
||||
rem if "%1"=="release" (
|
||||
rem copy te.exe ..\data\te.exe
|
||||
rem echo written ..\data\te.exe
|
||||
rem ) else (
|
||||
rem copy te.exe ..\data\te_debug.exe
|
||||
rem echo written ..\data\te_debug.exe
|
||||
rem )
|
||||
copy te.exe ..\data\te.exe
|
||||
echo written ..\data\te.exe
|
||||
|
||||
@@ -8,8 +8,8 @@ set rel=-O3 -DDEBUG_BUILD=0
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
clang ../src/metaprogram/metaprogram.cpp ../src/basic/win32.cpp -o metaprogram.exe %flags% -g -DDEBUG_BUILD=1 -I../src
|
||||
clang ../src/metaprogram/metaprogram.cpp -o metaprogram.exe %flags% -g -DDEBUG_BUILD=1 -I../src
|
||||
metaprogram.exe
|
||||
cd ..
|
||||
|
||||
emcc -o text_editor.html --shell-file=data/shell.html %flags% %incs% %wasmflags% %dbg% -lm -lSDL3 src/text_editor/text_editor.cpp src/basic/wasm.cpp src/external/luaunity.c src/external/glad/glad.c
|
||||
emcc -o text_editor.html --shell-file=data/shell.html %flags% %incs% %wasmflags% %dbg% -lm -lSDL3 src/text_editor/text_editor.cpp
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
-- {kind = 10, key = KEY_PAGE_DOWN, xmouse = 0, ymouse = 0, xwindow = 1280, ywindow = 720},
|
||||
-- {kind = 111},
|
||||
-- }
|
||||
-- -- for i = 1,8 do coroutine.yield() end
|
||||
-- while coroutine.yield().kind ~= 111 do end
|
||||
-- -- for i = 1,8 do coroutine.CoYield() end
|
||||
-- while coroutine.CoYield().kind ~= 111 do end
|
||||
|
||||
-- local buffer_name = GetActiveMainWindowBufferName()
|
||||
-- Print("buffer name = "..buffer_name)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <math.h>
|
||||
|
||||
struct Vec2 {
|
||||
float x;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#if OS_POSIX
|
||||
#include "filesystem.h"
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -862,7 +861,6 @@ API String PollStdout(Allocator allocator, Process *process, bool force_read) {
|
||||
}
|
||||
|
||||
#elif OS_WASM
|
||||
#include "filesystem.h"
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
Hash table implementation:
|
||||
Pointers to values
|
||||
@@ -11,7 +10,7 @@
|
||||
Hash 0 is reserved for empty hash table entry
|
||||
*/
|
||||
template <class Value>
|
||||
struct Table {
|
||||
struct HashTable {
|
||||
struct Entry {
|
||||
uint64_t hash;
|
||||
uint64_t key;
|
||||
|
||||
@@ -23,11 +23,19 @@ Rect2 operator-(Rect2 r, Vec2 value) { return { {r.min.x - value.x, r.min.y - va
|
||||
Rect2 operator+(Rect2 r, Vec2 value) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; }
|
||||
Rect2 operator*(Rect2 r, Vec2 value) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; }
|
||||
Rect2 operator/(Rect2 r, Vec2 value) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; }
|
||||
Rect2 operator-(Vec2 value, Rect2 r) { return { {r.min.x - value.x, r.min.y - value.y}, {r.max.x - value.x, r.max.y - value.y} }; }
|
||||
Rect2 operator+(Vec2 value, Rect2 r) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; }
|
||||
Rect2 operator*(Vec2 value, Rect2 r) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; }
|
||||
Rect2 operator/(Vec2 value, Rect2 r) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; }
|
||||
|
||||
Rect2 operator-(Rect2 r, float value) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; }
|
||||
Rect2 operator+(Rect2 r, float value) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; }
|
||||
Rect2 operator*(Rect2 r, float value) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; }
|
||||
Rect2 operator/(Rect2 r, float value) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; }
|
||||
Rect2 operator-(float value, Rect2 r) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; }
|
||||
Rect2 operator+(float value, Rect2 r) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; }
|
||||
Rect2 operator*(float value, Rect2 r) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; }
|
||||
Rect2 operator/(float value, Rect2 r) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; }
|
||||
|
||||
Rect2 operator-=(Rect2 &r, Rect2 value) { r = r - value; return r; }
|
||||
Rect2 operator+=(Rect2 &r, Rect2 value) { r = r + value; return r; }
|
||||
@@ -60,6 +68,10 @@ Vec2 operator-(Vec2 a, float b) { return {a.x - b, a.y - b}; }
|
||||
Vec2 operator+(Vec2 a, float b) { return {a.x + b, a.y + b}; }
|
||||
Vec2 operator*(Vec2 a, float b) { return {a.x * b, a.y * b}; }
|
||||
Vec2 operator/(Vec2 a, float b) { return {a.x / b, a.y / b}; }
|
||||
Vec2 operator-(float b, Vec2 a) { return {a.x - b, a.y - b}; }
|
||||
Vec2 operator+(float b, Vec2 a) { return {a.x + b, a.y + b}; }
|
||||
Vec2 operator*(float b, Vec2 a) { return {a.x * b, a.y * b}; }
|
||||
Vec2 operator/(float b, Vec2 a) { return {a.x / b, a.y / b}; }
|
||||
|
||||
Vec2 operator-=(Vec2 &a, Vec2 b) { a = a - b; return a; }
|
||||
Vec2 operator+=(Vec2 &a, Vec2 b) { a = a + b; return a; }
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
Vec2I GetSize(Rect2I r) {
|
||||
Vec2I result = {r.max.x - r.min.x, r.max.y - r.min.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
Rect2I operator-(Rect2I r, Rect2I value) { return { {r.min.x - value.min.x, r.min.y - value.min.y}, {r.max.x - value.max.x, r.max.y - value.max.y} }; }
|
||||
Rect2I operator+(Rect2I r, Rect2I value) { return { {r.min.x + value.min.x, r.min.y + value.min.y}, {r.max.x + value.max.x, r.max.y + value.max.y} }; }
|
||||
Rect2I operator*(Rect2I r, Rect2I value) { return { {r.min.x * value.min.x, r.min.y * value.min.y}, {r.max.x * value.max.x, r.max.y * value.max.y} }; }
|
||||
@@ -13,7 +7,15 @@ Rect2I operator-(Rect2I r, Vec2I value) { return { {r.min.x - value.x, r.min.y -
|
||||
Rect2I operator+(Rect2I r, Vec2I value) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; }
|
||||
Rect2I operator*(Rect2I r, Vec2I value) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; }
|
||||
Rect2I operator/(Rect2I r, Vec2I value) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; }
|
||||
Rect2I operator-(Vec2I value, Rect2I r) { return { {r.min.x - value.x, r.min.y - value.y}, {r.max.x - value.x, r.max.y - value.y} }; }
|
||||
Rect2I operator+(Vec2I value, Rect2I r) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; }
|
||||
Rect2I operator*(Vec2I value, Rect2I r) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; }
|
||||
Rect2I operator/(Vec2I value, Rect2I r) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; }
|
||||
|
||||
Rect2I operator-(Int value, Rect2I r) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; }
|
||||
Rect2I operator+(Int value, Rect2I r) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; }
|
||||
Rect2I operator*(Int value, Rect2I r) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; }
|
||||
Rect2I operator/(Int value, Rect2I r) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; }
|
||||
Rect2I operator-(Rect2I r, Int value) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; }
|
||||
Rect2I operator+(Rect2I r, Int value) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; }
|
||||
Rect2I operator*(Rect2I r, Int value) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; }
|
||||
@@ -41,6 +43,10 @@ Vec2I operator-(Vec2I a, Int b) { return {a.x - b, a.y - b}; }
|
||||
Vec2I operator+(Vec2I a, Int b) { return {a.x + b, a.y + b}; }
|
||||
Vec2I operator*(Vec2I a, Int b) { return {a.x * b, a.y * b}; }
|
||||
Vec2I operator/(Vec2I a, Int b) { return {a.x / b, a.y / b}; }
|
||||
Vec2I operator-(Int b, Vec2I a) { return {a.x - b, a.y - b}; }
|
||||
Vec2I operator+(Int b, Vec2I a) { return {a.x + b, a.y + b}; }
|
||||
Vec2I operator*(Int b, Vec2I a) { return {a.x * b, a.y * b}; }
|
||||
Vec2I operator/(Int b, Vec2I a) { return {a.x / b, a.y / b}; }
|
||||
|
||||
Vec2I operator-=(Vec2I &a, Vec2I b) { a = a - b; return a; }
|
||||
Vec2I operator+=(Vec2I &a, Vec2I b) { a = a + b; return a; }
|
||||
@@ -51,7 +57,10 @@ Vec2I operator+=(Vec2I &a, Int b) { a = a + b; return a; }
|
||||
Vec2I operator*=(Vec2I &a, Int b) { a = a * b; return a; }
|
||||
Vec2I operator/=(Vec2I &a, Int b) { a = a / b; return a; }
|
||||
|
||||
// clang-format on
|
||||
Vec2I GetSize(Rect2I r) {
|
||||
Vec2I result = {r.max.x - r.min.x, r.max.y - r.min.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
Rect2I RectI0Size(Int x, Int y) {
|
||||
Rect2I rect = {0, 0, x, y};
|
||||
|
||||
@@ -30,7 +30,10 @@ int main() {
|
||||
Scratch scratch;
|
||||
String16 a = Format16(scratch, "Memes %d", 30);
|
||||
Assert(a == u"Memes 30");
|
||||
|
||||
}
|
||||
{
|
||||
Vec2 a = {1,1};
|
||||
Vec2 b = 2 + a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,443 +0,0 @@
|
||||
// SPDX-FileCopyrightText: © 2023 Phillip Trudeau-Tavara <pmttavara@protonmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
|
||||
TODO: Optional Helper APIs:
|
||||
|
||||
- Compression API: would require a mutexed lockable context (yuck...)
|
||||
- Either using a ZIP library, a name cache + TIDPID cache, or both (but ZIP is likely more than enough!!!)
|
||||
- begin()/end() writes compressed chunks to a caller-determined destination
|
||||
- The destination can be the buffered-writing API or a custom user destination
|
||||
- Ultimately need to take a lock with some granularity... can that be the caller's responsibility?
|
||||
|
||||
- Counter Event: should allow tracking arbitrary named values with a single event, for memory and frame profiling
|
||||
|
||||
- Ring-buffer API
|
||||
spall_ring_init
|
||||
spall_ring_emit_begin
|
||||
spall_ring_emit_end
|
||||
spall_ring_flush
|
||||
*/
|
||||
|
||||
#ifndef SPALL_H
|
||||
#define SPALL_H
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
#define SPALL_NOINSTRUMENT __attribute__((no_instrument_function))
|
||||
#define SPALL_FORCEINLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define SPALL_NOINSTRUMENT // Can't noinstrument on MSVC!
|
||||
#define SPALL_FORCEINLINE __forceinline
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SPALL_FN static inline SPALL_NOINSTRUMENT
|
||||
|
||||
#define SPALL_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct SpallHeader {
|
||||
uint64_t magic_header; // = 0x0BADF00D
|
||||
uint64_t version; // = 1
|
||||
double timestamp_unit;
|
||||
uint64_t must_be_0;
|
||||
} SpallHeader;
|
||||
|
||||
enum {
|
||||
SpallEventType_Invalid = 0,
|
||||
SpallEventType_Custom_Data = 1, // Basic readers can skip this.
|
||||
SpallEventType_StreamOver = 2,
|
||||
|
||||
SpallEventType_Begin = 3,
|
||||
SpallEventType_End = 4,
|
||||
SpallEventType_Instant = 5,
|
||||
|
||||
SpallEventType_Overwrite_Timestamp = 6, // Retroactively change timestamp units - useful for incrementally improving RDTSC frequency.
|
||||
SpallEventType_Pad_Skip = 7,
|
||||
};
|
||||
|
||||
typedef struct SpallBeginEvent {
|
||||
uint8_t type; // = SpallEventType_Begin
|
||||
uint8_t category;
|
||||
|
||||
uint32_t pid;
|
||||
uint32_t tid;
|
||||
double when;
|
||||
|
||||
uint8_t name_length;
|
||||
uint8_t args_length;
|
||||
} SpallBeginEvent;
|
||||
|
||||
typedef struct SpallBeginEventMax {
|
||||
SpallBeginEvent event;
|
||||
char name_bytes[255];
|
||||
char args_bytes[255];
|
||||
} SpallBeginEventMax;
|
||||
|
||||
typedef struct SpallEndEvent {
|
||||
uint8_t type; // = SpallEventType_End
|
||||
uint32_t pid;
|
||||
uint32_t tid;
|
||||
double when;
|
||||
} SpallEndEvent;
|
||||
|
||||
typedef struct SpallPadSkipEvent {
|
||||
uint8_t type; // = SpallEventType_Pad_Skip
|
||||
uint32_t size;
|
||||
} SpallPadSkipEvent;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct SpallProfile SpallProfile;
|
||||
|
||||
// Important!: If you define your own callbacks, mark them SPALL_NOINSTRUMENT!
|
||||
typedef bool (*SpallWriteCallback)(SpallProfile *self, const void *data, size_t length);
|
||||
typedef bool (*SpallFlushCallback)(SpallProfile *self);
|
||||
typedef void (*SpallCloseCallback)(SpallProfile *self);
|
||||
|
||||
struct SpallProfile {
|
||||
double timestamp_unit;
|
||||
bool is_json;
|
||||
SpallWriteCallback write;
|
||||
SpallFlushCallback flush;
|
||||
SpallCloseCallback close;
|
||||
void *data;
|
||||
};
|
||||
|
||||
// Important!: If you are writing Begin/End events, then do NOT write
|
||||
// events for the same PID + TID pair on different buffers!!!
|
||||
typedef struct SpallBuffer {
|
||||
void *data;
|
||||
size_t length;
|
||||
|
||||
// Internal data - don't assign this
|
||||
size_t head;
|
||||
SpallProfile *ctx;
|
||||
} SpallBuffer;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(SPALL_BUFFER_PROFILING) && !defined(SPALL_BUFFER_PROFILING_GET_TIME)
|
||||
#error "You must #define SPALL_BUFFER_PROFILING_GET_TIME() to profile buffer flushes."
|
||||
#endif
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE void spall__buffer_profile(SpallProfile *ctx, SpallBuffer *wb, double spall_time_begin, double spall_time_end, const char *name, int name_len);
|
||||
#ifdef SPALL_BUFFER_PROFILING
|
||||
#define SPALL_BUFFER_PROFILE_BEGIN() double spall_time_begin = (SPALL_BUFFER_PROFILING_GET_TIME())
|
||||
// Don't call this with anything other than a string literal
|
||||
#define SPALL_BUFFER_PROFILE_END(name) spall__buffer_profile(ctx, wb, spall_time_begin, (SPALL_BUFFER_PROFILING_GET_TIME()), "" name "", sizeof("" name "") - 1)
|
||||
#else
|
||||
#define SPALL_BUFFER_PROFILE_BEGIN()
|
||||
#define SPALL_BUFFER_PROFILE_END(name)
|
||||
#endif
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE bool spall__file_write(SpallProfile *ctx, const void *p, size_t n) {
|
||||
if (!ctx->data) return false;
|
||||
#ifdef SPALL_DEBUG
|
||||
if (feof((FILE *)ctx->data)) return false;
|
||||
if (ferror((FILE *)ctx->data)) return false;
|
||||
#endif
|
||||
|
||||
if (fwrite(p, n, 1, (FILE *)ctx->data) != 1) return false;
|
||||
return true;
|
||||
}
|
||||
SPALL_FN bool spall__file_flush(SpallProfile *ctx) {
|
||||
if (!ctx->data) return false;
|
||||
if (fflush((FILE *)ctx->data)) return false;
|
||||
return true;
|
||||
}
|
||||
SPALL_FN void spall__file_close(SpallProfile *ctx) {
|
||||
if (!ctx->data) return;
|
||||
|
||||
if (ctx->is_json) {
|
||||
#ifdef SPALL_DEBUG
|
||||
if (!feof((FILE *)ctx->data) && !ferror((FILE *)ctx->data))
|
||||
#endif
|
||||
{
|
||||
fseek((FILE *)ctx->data, -2, SEEK_CUR); // seek back to overwrite trailing comma
|
||||
fwrite("\n]}\n", sizeof("\n]}\n") - 1, 1, (FILE *)ctx->data);
|
||||
}
|
||||
}
|
||||
fflush((FILE *)ctx->data);
|
||||
fclose((FILE *)ctx->data);
|
||||
ctx->data = NULL;
|
||||
}
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE bool spall__buffer_flush(SpallProfile *ctx, SpallBuffer *wb) {
|
||||
// precon: wb
|
||||
// precon: wb->data
|
||||
// precon: wb->head <= wb->length
|
||||
// precon: !ctx || ctx->write
|
||||
#ifdef SPALL_DEBUG
|
||||
if (wb->ctx != ctx) return false; // Buffer must be bound to this context (or to NULL)
|
||||
#endif
|
||||
|
||||
if (wb->head && ctx) {
|
||||
SPALL_BUFFER_PROFILE_BEGIN();
|
||||
if (!ctx->write) return false;
|
||||
if (ctx->write == spall__file_write) {
|
||||
if (!spall__file_write(ctx, wb->data, wb->head)) return false;
|
||||
} else {
|
||||
if (!ctx->write(ctx, wb->data, wb->head)) return false;
|
||||
}
|
||||
SPALL_BUFFER_PROFILE_END("Buffer Flush");
|
||||
}
|
||||
wb->head = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE bool spall__buffer_write(SpallProfile *ctx, SpallBuffer *wb, void *p, size_t n) {
|
||||
// precon: !wb || wb->head < wb->length
|
||||
// precon: !ctx || ctx->write
|
||||
if (!wb) return ctx->write && ctx->write(ctx, p, n);
|
||||
#ifdef SPALL_DEBUG
|
||||
if (wb->ctx != ctx) return false; // Buffer must be bound to this context (or to NULL)
|
||||
#endif
|
||||
if (wb->head + n > wb->length && !spall__buffer_flush(ctx, wb)) return false;
|
||||
if (n > wb->length) {
|
||||
SPALL_BUFFER_PROFILE_BEGIN();
|
||||
if (!ctx->write || !ctx->write(ctx, p, n)) return false;
|
||||
SPALL_BUFFER_PROFILE_END("Unbuffered Write");
|
||||
return true;
|
||||
}
|
||||
memcpy((char *)wb->data + wb->head, p, n);
|
||||
wb->head += n;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN bool spall_buffer_flush(SpallProfile *ctx, SpallBuffer *wb) {
|
||||
#ifdef SPALL_DEBUG
|
||||
if (!wb) return false;
|
||||
if (!wb->data) return false;
|
||||
#endif
|
||||
|
||||
if (!spall__buffer_flush(ctx, wb)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN bool spall_buffer_init(SpallProfile *ctx, SpallBuffer *wb) {
|
||||
if (!spall_buffer_flush(NULL, wb)) return false;
|
||||
wb->ctx = ctx;
|
||||
return true;
|
||||
}
|
||||
SPALL_FN bool spall_buffer_quit(SpallProfile *ctx, SpallBuffer *wb) {
|
||||
if (!spall_buffer_flush(ctx, wb)) return false;
|
||||
wb->ctx = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN bool spall_buffer_abort(SpallBuffer *wb) {
|
||||
if (!wb) return false;
|
||||
wb->ctx = NULL;
|
||||
if (!spall__buffer_flush(NULL, wb)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN size_t spall_build_header(void *buffer, size_t rem_size, double timestamp_unit) {
|
||||
size_t header_size = sizeof(SpallHeader);
|
||||
if (header_size > rem_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SpallHeader *header = (SpallHeader *)buffer;
|
||||
header->magic_header = 0x0BADF00D;
|
||||
header->version = 1;
|
||||
header->timestamp_unit = timestamp_unit;
|
||||
header->must_be_0 = 0;
|
||||
return header_size;
|
||||
}
|
||||
SPALL_FN SPALL_FORCEINLINE size_t spall_build_begin(void *buffer, size_t rem_size, const char *name, signed long name_len, const char *args, signed long args_len, double when, uint32_t tid, uint32_t pid) {
|
||||
SpallBeginEventMax *ev = (SpallBeginEventMax *)buffer;
|
||||
uint8_t trunc_name_len = (uint8_t)SPALL_MIN(name_len, 255); // will be interpreted as truncated in the app (?)
|
||||
uint8_t trunc_args_len = (uint8_t)SPALL_MIN(args_len, 255); // will be interpreted as truncated in the app (?)
|
||||
|
||||
size_t ev_size = sizeof(SpallBeginEvent) + trunc_name_len + trunc_args_len;
|
||||
if (ev_size > rem_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ev->event.type = SpallEventType_Begin;
|
||||
ev->event.category = 0;
|
||||
ev->event.pid = pid;
|
||||
ev->event.tid = tid;
|
||||
ev->event.when = when;
|
||||
ev->event.name_length = trunc_name_len;
|
||||
ev->event.args_length = trunc_args_len;
|
||||
memcpy(ev->name_bytes, name, trunc_name_len);
|
||||
memcpy(ev->name_bytes + trunc_name_len, args, trunc_args_len);
|
||||
|
||||
return ev_size;
|
||||
}
|
||||
SPALL_FN SPALL_FORCEINLINE size_t spall_build_end(void *buffer, size_t rem_size, double when, uint32_t tid, uint32_t pid) {
|
||||
size_t ev_size = sizeof(SpallEndEvent);
|
||||
if (ev_size > rem_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SpallEndEvent *ev = (SpallEndEvent *)buffer;
|
||||
ev->type = SpallEventType_End;
|
||||
ev->pid = pid;
|
||||
ev->tid = tid;
|
||||
ev->when = when;
|
||||
|
||||
return ev_size;
|
||||
}
|
||||
|
||||
SPALL_FN void spall_quit(SpallProfile *ctx) {
|
||||
if (!ctx) return;
|
||||
if (ctx->close) ctx->close(ctx);
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
SPALL_FN SpallProfile spall_init_callbacks(double timestamp_unit,
|
||||
SpallWriteCallback write,
|
||||
SpallFlushCallback flush,
|
||||
SpallCloseCallback close,
|
||||
void *userdata,
|
||||
bool is_json) {
|
||||
SpallProfile ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
if (timestamp_unit < 0) return ctx;
|
||||
ctx.timestamp_unit = timestamp_unit;
|
||||
ctx.is_json = is_json;
|
||||
ctx.data = userdata;
|
||||
ctx.write = write;
|
||||
ctx.flush = flush;
|
||||
ctx.close = close;
|
||||
|
||||
if (ctx.is_json) {
|
||||
if (!ctx.write(&ctx, "{\"traceEvents\":[\n", sizeof("{\"traceEvents\":[\n") - 1)) {
|
||||
spall_quit(&ctx);
|
||||
return ctx;
|
||||
}
|
||||
} else {
|
||||
SpallHeader header;
|
||||
size_t len = spall_build_header(&header, sizeof(header), timestamp_unit);
|
||||
if (!ctx.write(&ctx, &header, len)) {
|
||||
spall_quit(&ctx);
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
SPALL_FN SpallProfile spall_init_file_ex(const char *filename, double timestamp_unit, bool is_json) {
|
||||
SpallProfile ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
if (!filename) return ctx;
|
||||
ctx.data = fopen(filename, "wb"); // TODO: handle utf8 and long paths on windows
|
||||
if (ctx.data) { // basically freopen() but we don't want to force users to lug along another macro define
|
||||
fclose((FILE *)ctx.data);
|
||||
ctx.data = fopen(filename, "ab");
|
||||
}
|
||||
if (!ctx.data) {
|
||||
spall_quit(&ctx);
|
||||
return ctx;
|
||||
}
|
||||
ctx = spall_init_callbacks(timestamp_unit, spall__file_write, spall__file_flush, spall__file_close, ctx.data, is_json);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
SPALL_FN SpallProfile spall_init_file(const char *filename, double timestamp_unit) { return spall_init_file_ex(filename, timestamp_unit, false); }
|
||||
SPALL_FN SpallProfile spall_init_file_json(const char *filename, double timestamp_unit) { return spall_init_file_ex(filename, timestamp_unit, true); }
|
||||
|
||||
SPALL_FN bool spall_flush(SpallProfile *ctx) {
|
||||
#ifdef SPALL_DEBUG
|
||||
if (!ctx) return false;
|
||||
#endif
|
||||
|
||||
if (!ctx->flush || !ctx->flush(ctx)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, const char *args, signed long args_len, double when, uint32_t tid, uint32_t pid) {
|
||||
#ifdef SPALL_DEBUG
|
||||
if (!ctx) return false;
|
||||
if (!name) return false;
|
||||
if (name_len <= 0) return false;
|
||||
if (!wb) return false;
|
||||
#endif
|
||||
|
||||
if (ctx->is_json) {
|
||||
char buf[1024];
|
||||
int buf_len = snprintf(buf, sizeof(buf),
|
||||
"{\"ph\":\"B\",\"ts\":%f,\"pid\":%u,\"tid\":%u,\"name\":\"%.*s\",\"args\":\"%.*s\"},\n",
|
||||
when * ctx->timestamp_unit, pid, tid, (int)(uint8_t)name_len, name, (int)(uint8_t)args_len, args);
|
||||
if (buf_len <= 0) return false;
|
||||
if (buf_len >= sizeof(buf)) return false;
|
||||
if (!spall__buffer_write(ctx, wb, buf, buf_len)) return false;
|
||||
} else {
|
||||
if ((wb->head + sizeof(SpallBeginEventMax)) > wb->length) {
|
||||
if (!spall__buffer_flush(ctx, wb)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
wb->head += spall_build_begin((char *)wb->data + wb->head, wb->length - wb->head, name, name_len, args, args_len, when, tid, pid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_ex(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, double when, uint32_t tid, uint32_t pid) {
|
||||
return spall_buffer_begin_args(ctx, wb, name, name_len, "", 0, when, tid, pid);
|
||||
}
|
||||
|
||||
SPALL_FN bool spall_buffer_begin(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, double when) {
|
||||
return spall_buffer_begin_args(ctx, wb, name, name_len, "", 0, when, 0, 0);
|
||||
}
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE bool spall_buffer_end_ex(SpallProfile *ctx, SpallBuffer *wb, double when, uint32_t tid, uint32_t pid) {
|
||||
#ifdef SPALL_DEBUG
|
||||
if (!ctx) return false;
|
||||
if (!wb) return false;
|
||||
#endif
|
||||
|
||||
if (ctx->is_json) {
|
||||
char buf[512];
|
||||
int buf_len = snprintf(buf, sizeof(buf),
|
||||
"{\"ph\":\"E\",\"ts\":%f,\"pid\":%u,\"tid\":%u},\n",
|
||||
when * ctx->timestamp_unit, pid, tid);
|
||||
if (buf_len <= 0) return false;
|
||||
if (buf_len >= sizeof(buf)) return false;
|
||||
if (!spall__buffer_write(ctx, wb, buf, buf_len)) return false;
|
||||
} else {
|
||||
if ((wb->head + sizeof(SpallEndEvent)) > wb->length) {
|
||||
if (!spall__buffer_flush(ctx, wb)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
wb->head += spall_build_end((char *)wb->data + wb->head, wb->length - wb->head, when, tid, pid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SPALL_FN bool spall_buffer_end(SpallProfile *ctx, SpallBuffer *wb, double when) { return spall_buffer_end_ex(ctx, wb, when, 0, 0); }
|
||||
|
||||
SPALL_FN SPALL_FORCEINLINE void spall__buffer_profile(SpallProfile *ctx, SpallBuffer *wb, double spall_time_begin, double spall_time_end, const char *name, int name_len) {
|
||||
// precon: ctx
|
||||
// precon: ctx->write
|
||||
char temp_buffer_data[2048];
|
||||
SpallBuffer temp_buffer = {temp_buffer_data, sizeof(temp_buffer_data)};
|
||||
if (!spall_buffer_begin_ex(ctx, &temp_buffer, name, name_len, spall_time_begin, (uint32_t)(uintptr_t)wb->data, 4222222222)) return;
|
||||
if (!spall_buffer_end_ex(ctx, &temp_buffer, spall_time_end, (uint32_t)(uintptr_t)wb->data, 4222222222)) return;
|
||||
if (ctx->write) ctx->write(ctx, temp_buffer_data, temp_buffer.head);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SPALL_H
|
||||
@@ -20,7 +20,7 @@ void AddText(String string) {
|
||||
|
||||
void Wait(mco_coro *co) {
|
||||
Add(&EventPlayback, {111});
|
||||
for (Event *event = Yield(co); event->kind != 111; event = Yield(co)) {
|
||||
for (Event *event = CoYield(co); event->kind != 111; event = CoYield(co)) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -956,7 +956,7 @@ void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array<HistoryEntry> *stack, Arr
|
||||
For(entry->edits) {
|
||||
Range new_range = {it.range.min, it.range.min + it.string.len};
|
||||
String16 string = GetString(buffer, it.range);
|
||||
it.string = Copy(sys_allocator, string);
|
||||
it.string = Copy16(sys_allocator, string);
|
||||
it.range = new_range;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ void Command_MoveLine(View *view, int direction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String16 string = Copy(scratch, GetString(buffer, lines_to_move_range));
|
||||
String16 string = Copy16(scratch, GetString(buffer, lines_to_move_range));
|
||||
|
||||
AddEdit(&edits, lines_to_move_range, {});
|
||||
if (direction == DIR_DOWN) {
|
||||
@@ -478,7 +478,7 @@ void Command_DuplicateLine(View *view, int direction) {
|
||||
range.max = GetFullLineEnd(buffer, it.range.max, &eof);
|
||||
range.min = GetFullLineStart(buffer, it.range.min);
|
||||
range.min -= Clamp(eof, (Int)0, buffer->len);
|
||||
String16 string = Copy(scratch, GetString(buffer, range));
|
||||
String16 string = Copy16(scratch, GetString(buffer, range));
|
||||
|
||||
Int pos = direction == DIR_UP ? range.min : range.max;
|
||||
AddEdit(&edits, Rng(pos), string);
|
||||
@@ -765,14 +765,14 @@ void Command_Delete(View *view, int direction, bool ctrl = false) {
|
||||
if (to_delete == 0) to_delete = StyleIndentSize;
|
||||
to_delete = Clamp(to_delete, (Int)1, StyleIndentSize);
|
||||
for (Int i = 0; i < to_delete; i += 1) {
|
||||
it = MoveCaret(buffer, it, direction, false, SHIFT_PRESSED);
|
||||
it = MoveCaret(buffer, it, direction, false, SHIFT_PRESS);
|
||||
}
|
||||
|
||||
} else {
|
||||
it = MoveCaret(buffer, it, direction, ctrl, SHIFT_PRESSED);
|
||||
it = MoveCaret(buffer, it, direction, ctrl, SHIFT_PRESS);
|
||||
}
|
||||
} else {
|
||||
it = MoveCaret(buffer, it, direction, ctrl, SHIFT_PRESSED);
|
||||
it = MoveCaret(buffer, it, direction, ctrl, SHIFT_PRESS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1389,13 +1389,13 @@ String16 FetchLoadWord(void) {
|
||||
}
|
||||
|
||||
void SplitWindow(WindowSplitKind kind) {
|
||||
Window *window = CreateWindow();
|
||||
Window *window = CreateWind();
|
||||
View *view = OpenBufferView(ScratchBuffer->name);
|
||||
window->active_view = view->id;
|
||||
CreateTitlebar(window->id);
|
||||
CreateSearchBar(window->id);
|
||||
|
||||
Window *active_window = GetActiveWindow();
|
||||
Window *active_window = GetActiveWind();
|
||||
SplitWindowEx(NULL, &WindowSplits, active_window, window, kind);
|
||||
ActiveWindow = window->id;
|
||||
}
|
||||
|
||||
@@ -356,13 +356,13 @@ void OnCommand(Event event) {
|
||||
} else if (AltShiftPress(SDLK_DOWN)) {
|
||||
Command_CreateCursorVertical(active.view, DIR_DOWN);
|
||||
} else if (CtrlShiftPress(SDLK_DOWN)) {
|
||||
Command_Move(active.view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESS);
|
||||
} else if (AltPress(SDLK_DOWN)) {
|
||||
Command_MoveLine(active.view, DIR_DOWN);
|
||||
} else if (CtrlPress(SDLK_DOWN)) {
|
||||
Command_Move(active.view, DIR_DOWN, CTRL_PRESSED);
|
||||
} else if (ShiftPress(SDLK_DOWN)) {
|
||||
Command_Move(active.view, DIR_DOWN, false, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_DOWN, false, SHIFT_PRESS);
|
||||
} else if (Press(SDLK_DOWN)) {
|
||||
Command_Move(active.view, DIR_DOWN);
|
||||
}
|
||||
@@ -372,23 +372,23 @@ void OnCommand(Event event) {
|
||||
} else if (AltShiftPress(SDLK_UP)) {
|
||||
Command_CreateCursorVertical(active.view, DIR_UP);
|
||||
} else if (CtrlShiftPress(SDLK_UP)) {
|
||||
Command_Move(active.view, DIR_UP, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_UP, CTRL_PRESSED, SHIFT_PRESS);
|
||||
} else if (AltPress(SDLK_UP)) {
|
||||
Command_MoveLine(active.view, DIR_UP);
|
||||
} else if (CtrlPress(SDLK_UP)) {
|
||||
Command_Move(active.view, DIR_UP, CTRL_PRESSED);
|
||||
} else if (ShiftPress(SDLK_UP)) {
|
||||
Command_Move(active.view, DIR_UP, false, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_UP, false, SHIFT_PRESS);
|
||||
} else if (Press(SDLK_UP)) {
|
||||
Command_Move(active.view, DIR_UP);
|
||||
}
|
||||
|
||||
if (CtrlShiftPress(SDLK_LEFT)) {
|
||||
Command_Move(active.view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESS);
|
||||
} else if (CtrlPress(SDLK_LEFT)) {
|
||||
Command_Move(active.view, DIR_LEFT, CTRL_PRESSED);
|
||||
} else if (ShiftPress(SDLK_LEFT)) {
|
||||
Command_Move(active.view, DIR_LEFT, false, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_LEFT, false, SHIFT_PRESS);
|
||||
} else if (AltPress(SDLK_LEFT)) {
|
||||
ActiveWindow = SwitchWindow(DIR_LEFT)->id;
|
||||
} else if (Press(SDLK_LEFT)) {
|
||||
@@ -396,11 +396,11 @@ void OnCommand(Event event) {
|
||||
}
|
||||
|
||||
if (CtrlShiftPress(SDLK_RIGHT)) {
|
||||
Command_Move(active.view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESS);
|
||||
} else if (CtrlPress(SDLK_RIGHT)) {
|
||||
Command_Move(active.view, DIR_RIGHT, CTRL_PRESSED);
|
||||
} else if (ShiftPress(SDLK_RIGHT)) {
|
||||
Command_Move(active.view, DIR_RIGHT, false, SHIFT_PRESSED);
|
||||
Command_Move(active.view, DIR_RIGHT, false, SHIFT_PRESS);
|
||||
} else if (AltPress(SDLK_RIGHT)) {
|
||||
ActiveWindow = SwitchWindow(DIR_RIGHT)->id;
|
||||
} else if (Press(SDLK_RIGHT)) {
|
||||
@@ -429,7 +429,7 @@ void OnCommand(Event event) {
|
||||
}
|
||||
|
||||
if (ShiftPress(SDLK_PAGEUP)) {
|
||||
Command_MoveCursorsByPageSize(active.window, DIR_UP, SHIFT_PRESSED);
|
||||
Command_MoveCursorsByPageSize(active.window, DIR_UP, SHIFT_PRESS);
|
||||
} else if (CtrlPress(SDLK_PAGEUP)) {
|
||||
Command_SelectRangeOneCursor(active.view, Rng(0));
|
||||
} else if (Press(SDLK_PAGEUP)) {
|
||||
@@ -437,7 +437,7 @@ void OnCommand(Event event) {
|
||||
}
|
||||
|
||||
if (ShiftPress(SDLK_PAGEDOWN)) {
|
||||
Command_MoveCursorsByPageSize(active.window, DIR_DOWN, SHIFT_PRESSED);
|
||||
Command_MoveCursorsByPageSize(active.window, DIR_DOWN, SHIFT_PRESS);
|
||||
} else if (CtrlPress(SDLK_PAGEDOWN)) {
|
||||
Command_SelectRangeOneCursor(active.view, Rng(active.buffer->len));
|
||||
} else if (Press(SDLK_PAGEDOWN)) {
|
||||
@@ -445,13 +445,13 @@ void OnCommand(Event event) {
|
||||
}
|
||||
|
||||
if (ShiftPress(SDLK_HOME)) {
|
||||
Command_MoveCursorsToSide(active.view, DIR_LEFT, SHIFT_PRESSED);
|
||||
Command_MoveCursorsToSide(active.view, DIR_LEFT, SHIFT_PRESS);
|
||||
} else if (Press(SDLK_HOME)) {
|
||||
Command_MoveCursorsToSide(active.view, DIR_LEFT);
|
||||
}
|
||||
|
||||
if (ShiftPress(SDLK_END)) {
|
||||
Command_MoveCursorsToSide(active.view, DIR_RIGHT, SHIFT_PRESSED);
|
||||
Command_MoveCursorsToSide(active.view, DIR_RIGHT, SHIFT_PRESS);
|
||||
} else if (Press(SDLK_END)) {
|
||||
Command_MoveCursorsToSide(active.view, DIR_RIGHT);
|
||||
}
|
||||
@@ -459,7 +459,7 @@ void OnCommand(Event event) {
|
||||
if (CtrlShiftPress(SDLK_TAB)) {
|
||||
GotoForward(main.window);
|
||||
} else if (ShiftPress(SDLK_TAB)) {
|
||||
Command_IndentSelectedLines(active.view, SHIFT_PRESSED);
|
||||
Command_IndentSelectedLines(active.view, SHIFT_PRESS);
|
||||
} else if (CtrlPress(SDLK_TAB)) {
|
||||
GotoBackward(main.window);
|
||||
} else if (Press(SDLK_TAB)) {
|
||||
@@ -467,7 +467,7 @@ void OnCommand(Event event) {
|
||||
}
|
||||
|
||||
if (CtrlPress(SDLK_LEFTBRACKET)) {
|
||||
Command_IndentSelectedLines(active.view, SHIFT_PRESSED);
|
||||
Command_IndentSelectedLines(active.view, SHIFT_PRESS);
|
||||
}
|
||||
if (CtrlPress(SDLK_RIGHTBRACKET)) {
|
||||
Command_IndentSelectedLines(active.view);
|
||||
|
||||
@@ -33,7 +33,7 @@ void FreeClipboardGlobals() {
|
||||
|
||||
void SaveStringInClipboard(String16 string) {
|
||||
FreeClipboardGlobals();
|
||||
SavedClipboardString = Copy(SysAllocator, string);
|
||||
SavedClipboardString = Copy16(SysAllocator, string);
|
||||
SetClipboardText(string);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void Command_Copy(View *view) {
|
||||
|
||||
For(view->carets) {
|
||||
String16 string = GetString(buffer, it.range);
|
||||
String16 copy = Copy(SysAllocator, string);
|
||||
String16 copy = Copy16(SysAllocator, string);
|
||||
Add(&SavedClipboardCarets, copy);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ void UpdateCo(Event *event) {
|
||||
}
|
||||
}
|
||||
|
||||
Event *Yield(mco_coro *co) {
|
||||
Event *CoYield(mco_coro *co) {
|
||||
mco_result ok = mco_yield(co);
|
||||
Assert(ok == MCO_SUCCESS);
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ const int DIR_DOWN = 2;
|
||||
const int DIR_UP = 3;
|
||||
const int DIR_COUNT = 4;
|
||||
const bool CTRL_PRESSED = true;
|
||||
bool SHIFT_PRESSED = true;
|
||||
const bool SHIFT_PRESS = true;
|
||||
|
||||
bool AppIsRunning = true;
|
||||
bool WaitForEvents = true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
struct InternTable {
|
||||
Table<String> strings;
|
||||
HashTable<String> strings;
|
||||
Arena *arena;
|
||||
};
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ inline View *GetView(ViewID id) {
|
||||
}
|
||||
|
||||
inline bool IsNull(Buffer *buffer) { return buffer->id.id == NullBufferID.id; }
|
||||
inline Window *GetActiveWindow() { return GetWindow(ActiveWindow); }
|
||||
inline Window *GetActiveWind() { return GetWindow(ActiveWindow); }
|
||||
|
||||
void InitBuffer(Allocator allocator, Buffer *buffer, String name, Int size = 4096) {
|
||||
buffer->id = AllocBufferID(buffer);
|
||||
@@ -180,7 +180,7 @@ Buffer *CreateTempBuffer(Allocator allocator, Int size = 4096) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Window *CreateWindow(bool create_command_buffer = true) {
|
||||
Window *CreateWind(bool create_command_buffer = true) {
|
||||
Window *w = AllocType(SysAllocator, Window);
|
||||
w->visible = true;
|
||||
w->draw_scrollbar = StyleDrawScrollbar;
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
#include <math.h>
|
||||
|
||||
#define BASIC_IMPL
|
||||
#include "basic/basic.h"
|
||||
#include "basic/filesystem.h"
|
||||
#include "basic/linked_list.h"
|
||||
|
||||
#include "basic/string16.cpp"
|
||||
#include "basic/math_int.cpp"
|
||||
#include "basic/math.cpp"
|
||||
#include "profiler/profiler.cpp"
|
||||
#include "basic/basic.cpp"
|
||||
#include "profiler.h"
|
||||
|
||||
#include "SDL3/SDL.h"
|
||||
#include "external/glad/glad.c"
|
||||
#include "external/glad/glad.h"
|
||||
#include "external/stb_truetype.h"
|
||||
#include "external/stb_truetype.c"
|
||||
#define MINICORO_IMPL
|
||||
#include "external/minicoro.h"
|
||||
#include "lua.hpp"
|
||||
#define LUA_USE_LONGJMP
|
||||
#include "external/luaunity.c"
|
||||
#include "render/generated_font.cpp"
|
||||
|
||||
SDL_Window *SDLWindow;
|
||||
@@ -313,7 +307,7 @@ void Windows_SetupVCVarsall(mco_coro *co) {
|
||||
if (!ProcessIsActive(view->id)) {
|
||||
break;
|
||||
}
|
||||
Yield(co);
|
||||
CoYield(co);
|
||||
}
|
||||
|
||||
Scratch scratch;
|
||||
@@ -359,7 +353,7 @@ void MainLoop() {
|
||||
// This shouldn't matter to the state of the program, only appearance for
|
||||
// the user
|
||||
{
|
||||
Window *window = GetActiveWindow();
|
||||
Window *window = GetActiveWind();
|
||||
View *view = GetView(window->active_view);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
const char *dirty = buffer->dirty ? " !" : "";
|
||||
@@ -383,7 +377,7 @@ void MainLoop() {
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
int WinMain(void *hInstance, void *hPrevInstance, const char *lpCmdLine, int nShowCmd)
|
||||
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||
#else
|
||||
extern char **environ;
|
||||
int main(int argc, char **argv)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
void UpdateDebugBuffer() {
|
||||
Buffer *buffer = GetBuffer(DebugBufferID);
|
||||
|
||||
Window *window = GetActiveWindow();
|
||||
Window *window = GetActiveWind();
|
||||
View *view = GetView(window->active_view);
|
||||
if (view->active_buffer.id == buffer->id.id) return;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Array<Window *> GetWindowZOrder(Allocator allocator) {
|
||||
}
|
||||
|
||||
Window *CreateSearchBar(WindowID parent_window_id) {
|
||||
Window *window = CreateWindow(false);
|
||||
Window *window = CreateWind(false);
|
||||
window->draw_scrollbar = false;
|
||||
window->deactivate_on_escape = true;
|
||||
window->is_search_bar = true;
|
||||
@@ -30,7 +30,7 @@ Window *CreateSearchBar(WindowID parent_window_id) {
|
||||
}
|
||||
|
||||
Window *CreateTitlebar(WindowID parent_window_id) {
|
||||
Window *window = CreateWindow(false);
|
||||
Window *window = CreateWind(false);
|
||||
window->draw_scrollbar = false;
|
||||
window->deactivate_on_escape = true;
|
||||
window->is_title_bar = true;
|
||||
@@ -161,7 +161,7 @@ void InitWindows() {
|
||||
split->value = (double)0.9;
|
||||
|
||||
{
|
||||
Window *window = CreateWindow();
|
||||
Window *window = CreateWind();
|
||||
window->active_view = NullViewID;
|
||||
Assert(window->id.id == 0);
|
||||
CreateTitlebar(window->id);
|
||||
@@ -171,7 +171,7 @@ void InitWindows() {
|
||||
}
|
||||
|
||||
{
|
||||
Window *window = CreateWindow();
|
||||
Window *window = CreateWind();
|
||||
Buffer *buffer = ScratchBuffer;
|
||||
View *view = CreateView(buffer->id);
|
||||
window->active_view = view->id;
|
||||
@@ -183,7 +183,7 @@ void InitWindows() {
|
||||
}
|
||||
|
||||
{
|
||||
Window *window = CreateWindow();
|
||||
Window *window = CreateWind();
|
||||
DebugWindowID = window->id;
|
||||
window->draw_line_numbers = false;
|
||||
window->draw_scrollbar = false;
|
||||
|
||||
@@ -46,17 +46,13 @@ void DrawVisibleText(Window *window, Color tint) {
|
||||
Rect2I visible = GetVisibleCells(window);
|
||||
for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < buffer->line_starts.len; line_index += 1) {
|
||||
String16 line_string = GetLineString(buffer, line_index);
|
||||
|
||||
Vec2I pos = {visible.min.x * (Int)FontCharSpacing, line_index * (Int)FontLineSpacing};
|
||||
pos -= view->scroll;
|
||||
pos += window->document_rect.min;
|
||||
Vec2I pos = Vec2I{visible.min.x, line_index} * (Int)FontLineSpacing - view->scroll + window->document_rect.min;
|
||||
|
||||
float text_offset_x = 0;
|
||||
for (Int col_index = visible.min.x; col_index < visible.max.x && col_index >= 0 && col_index < line_string.len; col_index += 1) {
|
||||
int codepoint = line_string[col_index];
|
||||
Glyph *g = GetGlyph(&MainFont, codepoint);
|
||||
Vec2 p = ToVec2(pos);
|
||||
// p.y += MainFont.ascent - MainFont.descent;
|
||||
p.y += FontLineSpacing + MainFont.descent;
|
||||
p.x += text_offset_x;
|
||||
Rect2 rect = Rect2FromSize(p + g->offset, g->size);
|
||||
@@ -84,9 +80,8 @@ void DrawCaret(Window *window, XY xy, float size, Color color) {
|
||||
View *view = GetView(window->active_view);
|
||||
Rect2I _rect = XYToRect(view, xy);
|
||||
Rect2I rect = CutLeft(&_rect, (Int)(size * (float)FontCharSpacing));
|
||||
rect -= view->scroll;
|
||||
rect += window->document_rect.min;
|
||||
DrawRect(ToRect2(rect), color);
|
||||
Rect2I scrolled_rect = rect - view->scroll + window->document_rect.min;
|
||||
DrawRect(ToRect2(scrolled_rect), color);
|
||||
}
|
||||
|
||||
void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range, Color color, Int size = 1) {
|
||||
@@ -100,9 +95,8 @@ void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range, Colo
|
||||
Vec2I min = {xy_min.col * FontCharSpacing, (xy_min.line + 1) * FontLineSpacing - size};
|
||||
Vec2I max = {xy_max.col * FontCharSpacing, (xy_max.line + 1) * FontLineSpacing};
|
||||
Rect2I rect = {min, max};
|
||||
rect -= view->scroll;
|
||||
rect += window->document_rect.min;
|
||||
DrawRectOutline(rect, color);
|
||||
Rect2I scrolled_rect = rect - view->scroll + window->document_rect.min;
|
||||
DrawRectOutline(scrolled_rect, color);
|
||||
}
|
||||
|
||||
void DrawWindow(Window *window, Event &event) {
|
||||
@@ -179,15 +173,12 @@ void DrawWindow(Window *window, Event &event) {
|
||||
bool c = min.line != max.line && (line == max.line && col < max.col);
|
||||
bool d = min.line == max.line && line == max.line && col >= min.col && col < max.col;
|
||||
if (!(a || b || c || d)) continue;
|
||||
Vec2I pos = {col * FontCharSpacing, line * FontLineSpacing};
|
||||
pos -= view->scroll;
|
||||
pos += window->document_rect.min;
|
||||
if (line_string[col] == ' ' || line_string[col] == '\t') {
|
||||
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, (float)pos.y + xglyph->size.y}, MainFont.size / 16.f, color_whitespace_during_selection);
|
||||
} else if (line_string[col] == '\n') {
|
||||
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, (float)pos.y + xglyph->size.y}, MainFont.size / 16.f, color_whitespace_during_selection);
|
||||
} else if (line_string[col] == '\r') {
|
||||
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, (float)pos.y + xglyph->size.y}, MainFont.size / 16.f, color_whitespace_during_selection);
|
||||
if (line_string[col] == ' ' || line_string[col] == '\t' || line_string[col] == '\n' || line_string[col] == '\r') {
|
||||
Vec2I pos = {col * FontCharSpacing, line * FontLineSpacing};
|
||||
Vec2I scrolled_pos = pos - view->scroll + window->document_rect.min;
|
||||
Vec2 circle_pos = {scrolled_pos.x + (float)FontCharSpacing / 2.f, (float)scrolled_pos.y + xglyph->size.y};
|
||||
float circle_size = MainFont.size / 16.f;
|
||||
DrawCircle(circle_pos, circle_size, color_whitespace_during_selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,13 +186,12 @@ void DrawWindow(Window *window, Event &event) {
|
||||
//
|
||||
// Draw highlight
|
||||
Int front = GetFront(it);
|
||||
XY fxy = PosToXY(buffer, front);
|
||||
Vec2I w = XYToWorldPos(view, XYLine(fxy.line));
|
||||
w -= view->scroll;
|
||||
w += window->document_rect.min;
|
||||
XY fxy = PosToXY(buffer, front);
|
||||
Vec2I pos = XYToWorldPos(view, XYLine(fxy.line));
|
||||
Vec2I scrolled_pos = pos - view->scroll + window->document_rect.min;
|
||||
Rect2 rect = {
|
||||
{(float)window->total_rect.min.x, (float)w.y},
|
||||
{(float)window->total_rect.max.x, (float)w.y + (float)FontLineSpacing}
|
||||
{(float)window->total_rect.min.x, (float)scrolled_pos.y},
|
||||
{(float)window->total_rect.max.x, (float)scrolled_pos.y + (float)FontLineSpacing}
|
||||
};
|
||||
DrawRect(rect, color_line_highlight);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user