Fix memory issues because of pointer to item in dynamic array, add clang-cl, add address sanitizer stuff
This commit is contained in:
@@ -4,16 +4,27 @@ enum {
|
||||
PROFILE_DEBUG,
|
||||
PROFILE_RELEASE,
|
||||
};
|
||||
int Profile = PROFILE_DEBUG;
|
||||
int Profile = PROFILE_DEBUG;
|
||||
S8_String Compiler = "cl.exe";
|
||||
|
||||
void AddCommonFlags(Array<S8_String> *cmd) {
|
||||
cmd->add("/MP /Zi /FC /nologo");
|
||||
if (Compiler == "cl.exe") {
|
||||
cmd->add("/MP");
|
||||
}
|
||||
cmd->add("/Zi /FC /nologo");
|
||||
cmd->add("/WX /W3 /wd4200 /diagnostics:column");
|
||||
if (Compiler == "clang-cl.exe") {
|
||||
cmd->add("-fdiagnostics-absolute-paths");
|
||||
cmd->add("-Wno-missing-braces");
|
||||
cmd->add("-Wno-writable-strings");
|
||||
cmd->add("-Wno-unused-function");
|
||||
}
|
||||
cmd->add("/Oi");
|
||||
cmd->add("-D_CRT_SECURE_NO_WARNINGS");
|
||||
if (Profile == PROFILE_DEBUG) {
|
||||
cmd->add("-DDEBUG_BUILD=1");
|
||||
cmd->add("-DRELEASE_BUILD=0");
|
||||
cmd->add("-fsanitize=address");
|
||||
// cmd->add("-D_DEBUG /MDd");
|
||||
} else {
|
||||
cmd->add("-DDEBUG_BUILD=0");
|
||||
@@ -87,7 +98,8 @@ Library PrepareLua() {
|
||||
|
||||
if (!OS_FileExists(l.objects[0])) {
|
||||
Array<S8_String> cmd = {};
|
||||
cmd.add("cl.exe -c");
|
||||
cmd.add(Compiler);
|
||||
cmd.add("-c");
|
||||
AddCommonFlags(&cmd);
|
||||
For(l.include_paths) cmd.add(S8_Format(Perm, "-I %.*s ", S8_Expand(it)));
|
||||
cmd += l.sources;
|
||||
@@ -103,7 +115,8 @@ Library PrepareGlad() {
|
||||
l.objects.add("glad.obj");
|
||||
if (!OS_FileExists(l.objects[0])) {
|
||||
Array<S8_String> cmd = {};
|
||||
cmd.add("cl.exe -c");
|
||||
cmd.add(Compiler);
|
||||
cmd.add("-c");
|
||||
AddCommonFlags(&cmd);
|
||||
For(l.include_paths) cmd.add(S8_Format(Perm, "-I %.*s ", S8_Expand(it)));
|
||||
cmd += l.sources;
|
||||
@@ -121,7 +134,7 @@ int CompileTextEditor() {
|
||||
libs.add(PrepareGlad());
|
||||
|
||||
Array<S8_String> cmd = {};
|
||||
cmd.add("cl.exe");
|
||||
cmd.add(Compiler);
|
||||
cmd.add("-Fe:te.exe");
|
||||
cmd.add("-Fd:te.pdb");
|
||||
cmd.add("-I ../src");
|
||||
@@ -147,39 +160,6 @@ int CompileTextEditor() {
|
||||
return result;
|
||||
}
|
||||
|
||||
int CompileNewPlatform() {
|
||||
int result = 0;
|
||||
|
||||
Array<Library> libs = {};
|
||||
libs.add(PrepareGlad());
|
||||
libs.add(PrepareLua());
|
||||
libs.add(PrepareSDLDynamic());
|
||||
|
||||
Array<S8_String> cmd = {};
|
||||
cmd.add("cl.exe");
|
||||
cmd.add("-Fe:te.exe");
|
||||
cmd.add("-Fd:te.pdb");
|
||||
cmd.add("-I ../src");
|
||||
AddCommonFlags(&cmd);
|
||||
For2(lib, libs) For(lib.defines) cmd.add(it);
|
||||
|
||||
cmd.add("../src/platform/platform.cpp");
|
||||
cmd.add("../src/basic/win32.cpp");
|
||||
|
||||
For2(lib, libs) For(lib.include_paths) cmd.add(Fmt("-I %.*s", S8_Expand(it)));
|
||||
|
||||
cmd.add("/link");
|
||||
cmd.add("/incremental:no");
|
||||
For2(lib, libs) For(lib.link) cmd.add(it);
|
||||
For(libs) For2(o, it.objects) cmd.add(o);
|
||||
|
||||
OS_DeleteFile("te.pdb");
|
||||
// For(cmd) IO_Printf("%.*s\n", S8_Expand(it));
|
||||
|
||||
result += Run(cmd);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *C(const char *value) {
|
||||
if (value[0] == '0' && value[1] == 'x') {
|
||||
S8_String f = Fmt("{0x%.*s, 0x%.*s, 0x%.*s, 0x%.*s}", 2, value + 2, 2, value + 4, 2, value + 6, 2, value + 8);
|
||||
|
||||
@@ -442,6 +442,12 @@ void BoundedAdd(Array<T> *arr, T item) {
|
||||
if (arr->len + 1 <= arr->cap) arr->data[arr->len++] = item;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void BoundedAddError(Array<T> *arr, T item) {
|
||||
Assert(arr->len + 1 <= arr->cap);
|
||||
if (arr->len + 1 <= arr->cap) arr->data[arr->len++] = item;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T *Alloc(Array<T> *arr, T item) {
|
||||
TryGrowing(arr);
|
||||
@@ -790,7 +796,7 @@ int64_t CreateWidecharFromChar(wchar_t *buffer, int64_t buffer_size, char *i
|
||||
inline bool operator==(String a, String b) { return AreEqual(a, b); }
|
||||
inline bool operator!=(String a, String b) { return !AreEqual(a, b); }
|
||||
|
||||
#if defined(__has_attribute)
|
||||
#if defined(__has_attribute) && defined(_MSC_VER) && !defined(__clang__)
|
||||
#if __has_attribute(format)
|
||||
#define PrintfFormatAttribute(fmt, va) __attribute__((format(printf, fmt, va)))
|
||||
#endif
|
||||
@@ -1598,6 +1604,22 @@ String ToString(Allocator allocator, wchar_t *wstring) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#if DEBUG_BUILD
|
||||
#define USE_ADDRESS_SANITIZER
|
||||
#endif
|
||||
|
||||
#if defined(USE_ADDRESS_SANITIZER)
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
#if !defined(ASAN_POISON_MEMORY_REGION)
|
||||
#define MA_ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
|
||||
#define MA_ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
|
||||
#else
|
||||
#define MA_ASAN_POISON_MEMORY_REGION(addr, size) ASAN_POISON_MEMORY_REGION(addr, size)
|
||||
#define MA_ASAN_UNPOISON_MEMORY_REGION(addr, size) ASAN_UNPOISON_MEMORY_REGION(addr, size)
|
||||
#endif
|
||||
|
||||
void InitArena(Arena *arena, size_t reserve) {
|
||||
reserve = AlignUp(reserve, PAGE_SIZE);
|
||||
arena->align = DEFAULT_ALIGNMENT;
|
||||
@@ -1647,7 +1669,6 @@ void *PushSize(Arena *arena, size_t size) {
|
||||
if (arena->align) {
|
||||
align_offset = GetAlignOffset((uintptr_t)arena->data + arena->len, arena->align);
|
||||
}
|
||||
size_t align_len = arena->len + align_offset;
|
||||
size_t size_with_alignment = size + align_offset;
|
||||
size_t new_len = arena->len + size_with_alignment;
|
||||
if (new_len > arena->commit) {
|
||||
@@ -1656,7 +1677,10 @@ void *PushSize(Arena *arena, size_t size) {
|
||||
size_t to_commit_clamped = ClampTop(to_commit, arena->reserve);
|
||||
if (to_commit_clamped > 0) {
|
||||
bool success = VCommit(arena->data + arena->commit, to_commit_clamped);
|
||||
if (success) arena->commit += to_commit_clamped;
|
||||
if (success) {
|
||||
MA_ASAN_UNPOISON_MEMORY_REGION(arena->data + arena->commit, to_commit_clamped);
|
||||
arena->commit += to_commit_clamped;
|
||||
}
|
||||
}
|
||||
if (new_len > arena->commit) {
|
||||
return NULL;
|
||||
@@ -1664,6 +1688,7 @@ void *PushSize(Arena *arena, size_t size) {
|
||||
}
|
||||
uint8_t *result = arena->data + arena->len + align_offset;
|
||||
arena->len = new_len;
|
||||
MA_ASAN_UNPOISON_MEMORY_REGION(result, size);
|
||||
return (void *)result;
|
||||
}
|
||||
|
||||
@@ -1674,6 +1699,18 @@ void Release(Arena *arena) {
|
||||
if (zero_memory) MemoryZero(arena, sizeof(Arena));
|
||||
}
|
||||
|
||||
void PopToPos(Arena *arena, size_t pos) {
|
||||
// base_len is used for bootstraping arenas, it denotes the
|
||||
// space occupied by the arena. If len is smaller then base_len then
|
||||
// we start to overwrite the arena itself - pure barbarism.
|
||||
Assert(arena->len >= arena->base_len);
|
||||
|
||||
pos = Clamp(pos, arena->base_len, arena->len);
|
||||
size_t size = arena->len - pos;
|
||||
arena->len = pos;
|
||||
MA_ASAN_POISON_MEMORY_REGION(arena->data + arena->len, size);
|
||||
}
|
||||
|
||||
void *ArenaAllocatorProc(void *object, int kind, void *p, size_t size) {
|
||||
if (kind == AllocatorKind_Allocate) {
|
||||
return PushSize((Arena *)object, size);
|
||||
|
||||
@@ -52,20 +52,20 @@ Rect2I ToRect2I(Rect2 r) { return {ToVec2I(r.min), ToVec2I(r.max)}; }
|
||||
Rect2 ToRect2(Rect2I r) { return {ToVec2(r.min), ToVec2(r.max)}; }
|
||||
|
||||
// clang-format off
|
||||
Rect2 operator-(Rect2 r, Rect2 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 }; }
|
||||
Rect2 operator+(Rect2 r, Rect2 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 }; }
|
||||
Rect2 operator*(Rect2 r, Rect2 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 }; }
|
||||
Rect2 operator/(Rect2 r, Rect2 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 }; }
|
||||
Rect2 operator-(Rect2 r, Rect2 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} }; }
|
||||
Rect2 operator+(Rect2 r, Rect2 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} }; }
|
||||
Rect2 operator*(Rect2 r, Rect2 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} }; }
|
||||
Rect2 operator/(Rect2 r, Rect2 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} }; }
|
||||
|
||||
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/(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*(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, 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-(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-=(Rect2 &r, Rect2 value) { r = r - value; return r; }
|
||||
Rect2 operator+=(Rect2 &r, Rect2 value) { r = r + value; return r; }
|
||||
|
||||
@@ -24,20 +24,20 @@ Vec2I GetSize(Rect2I r) {
|
||||
}
|
||||
|
||||
// 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 }; }
|
||||
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} }; }
|
||||
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, 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/(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*(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, 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 }; }
|
||||
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} }; }
|
||||
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, Rect2I value) { r = r - value; return r; }
|
||||
Rect2I operator+=(Rect2I &r, Rect2I value) { r = r + value; return r; }
|
||||
|
||||
@@ -46,7 +46,10 @@ Atlas CreateAtlas(Allocator allocator, Vec2I size) {
|
||||
}
|
||||
}
|
||||
|
||||
result.white_texture_bounding_box = {2.f * result.inverse_size.x, 2.f / (float)result.size.y, 14.f * result.inverse_size.x, 14.f / (float)result.size.y};
|
||||
result.white_texture_bounding_box = {
|
||||
{ 2.f * result.inverse_size.x, 2.f / (float)result.size.y},
|
||||
{14.f * result.inverse_size.x, 14.f / (float)result.size.y}
|
||||
};
|
||||
result.xcursor += 16;
|
||||
result.biggest_height += 16;
|
||||
return result;
|
||||
@@ -90,10 +93,12 @@ Rect2 PackBitmap(Atlas *atlas, uint8_t *bitmap, int width, int height) {
|
||||
}
|
||||
|
||||
Font CreateFont(Atlas *atlas, int32_t size, String path) {
|
||||
Scratch scratch;
|
||||
Font result = {};
|
||||
Allocator allocator = GetSystemAllocator();
|
||||
Scratch scratch;
|
||||
|
||||
String file = ReadFile(scratch, path);
|
||||
Font result = {};
|
||||
result.glyphs.allocator = allocator;
|
||||
String file = ReadFile(allocator, path);
|
||||
if (file.len == 0) {
|
||||
return result;
|
||||
}
|
||||
@@ -104,8 +109,8 @@ Font CreateFont(Atlas *atlas, int32_t size, String path) {
|
||||
return result;
|
||||
}
|
||||
|
||||
float scale = stbtt_ScaleForPixelHeight(&stb_font, (float)size);
|
||||
float em_scale = stbtt_ScaleForMappingEmToPixels(&stb_font, (float)size);
|
||||
float scale = stbtt_ScaleForPixelHeight(&stb_font, (float)size);
|
||||
// float em_scale = stbtt_ScaleForMappingEmToPixels(&stb_font, (float)size);
|
||||
|
||||
int ascent, descent, line_gap;
|
||||
stbtt_GetFontVMetrics(&stb_font, &ascent, &descent, &line_gap);
|
||||
@@ -117,6 +122,9 @@ Font CreateFont(Atlas *atlas, int32_t size, String path) {
|
||||
result.last_char = '~';
|
||||
result.white_texture_bounding_box = atlas->white_texture_bounding_box;
|
||||
|
||||
int glyph_count = result.last_char - result.first_char + 1; // + 1 because it's '<=' not '<'
|
||||
Reserve(&result.glyphs, glyph_count);
|
||||
|
||||
for (uint32_t ascii_symbol = result.first_char; ascii_symbol <= result.last_char; ascii_symbol++) {
|
||||
int width, height, xoff, yoff;
|
||||
uint8_t *bitmap = (uint8_t *)stbtt_GetCodepointBitmap(&stb_font, 0, scale, ascii_symbol, &width, &height, &xoff, &yoff);
|
||||
|
||||
@@ -74,8 +74,8 @@ void EndFrameRender(Color color) {
|
||||
Rect2 rect = it->scissor;
|
||||
GLint x = (GLint)rect.min.x;
|
||||
GLint y = (GLint)rect.min.y;
|
||||
GLsizei w = (GLsizei)(rect.max.x - rect.min.x);
|
||||
GLsizei h = (GLsizei)(rect.max.y - rect.min.y);
|
||||
GLsizei w = (GLsizei)(rect.max.x - x);
|
||||
GLsizei h = (GLsizei)(rect.max.y - y);
|
||||
glScissor(x, (GLint)WindowSize.y - (GLint)rect.max.y, w, h);
|
||||
glNamedBufferSubData(VBO, 0, it->count * sizeof(Vertex2D), it->vertices);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
@@ -79,6 +79,15 @@ void ToggleFullscreen() {
|
||||
IsInFullscreen = !IsInFullscreen;
|
||||
}
|
||||
|
||||
void ToggleConsole() {
|
||||
Window *window = GetWindow(ConsoleWindowID);
|
||||
if (ToggleVisibility(window)) {
|
||||
SetActiveWindow(window->id);
|
||||
} else {
|
||||
SetActiveWindow(GetLastActiveWindow());
|
||||
}
|
||||
}
|
||||
|
||||
struct GotoCrumb {
|
||||
BufferID buffer_id;
|
||||
Caret caret;
|
||||
@@ -282,6 +291,7 @@ bool GlobalCommand(Event event) {
|
||||
if (event.ctrl && Mouse(RIGHT)) {
|
||||
GoBackToLastCrumb();
|
||||
} else if (event.alt && Mouse(RIGHT)) {
|
||||
ToggleConsole();
|
||||
}
|
||||
|
||||
// @todo: maybe move some of this stuff to window command ???
|
||||
@@ -393,12 +403,7 @@ bool GlobalCommand(Event event) {
|
||||
}
|
||||
|
||||
if (Ctrl(SDLK_GRAVE)) {
|
||||
Window *window = GetWindow(ConsoleWindowID);
|
||||
if (ToggleVisibility(window)) {
|
||||
SetActiveWindow(window->id);
|
||||
} else {
|
||||
SetActiveWindow(GetLastActiveWindow());
|
||||
}
|
||||
ToggleConsole();
|
||||
}
|
||||
|
||||
if (CtrlShift(SDLK_BACKSLASH)) {
|
||||
|
||||
@@ -374,7 +374,6 @@ void Command_SelectAll(View *view, String16 needle) {
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
String16 string_buffer = GetString(*buffer);
|
||||
|
||||
Int debug_id = 0;
|
||||
for (Int pos = 0;;) {
|
||||
Int index = 0;
|
||||
String16 medium = Skip(string_buffer, pos);
|
||||
@@ -384,7 +383,6 @@ void Command_SelectAll(View *view, String16 needle) {
|
||||
|
||||
Add(&view->carets, MakeCaret(pos + index + needle.len, pos + index));
|
||||
pos += needle.len;
|
||||
debug_id += 1;
|
||||
}
|
||||
MergeCarets(view);
|
||||
}
|
||||
@@ -415,7 +413,6 @@ void Command_CreateCursorVertical(View *_view, int direction) {
|
||||
}
|
||||
|
||||
void Command_SelectRangeOneCursor(View *view, Range range) {
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
view->carets.len = 1;
|
||||
view->carets[0] = MakeCaret(range.min, range.max);
|
||||
}
|
||||
@@ -805,6 +802,8 @@ void WindowCommand(Event event, Window *window, View *view) {
|
||||
|
||||
if (Ctrl(SDLK_W)) {
|
||||
GoBackToLastCrumb();
|
||||
} else if (Alt(SDLK_W)) {
|
||||
ToggleConsole();
|
||||
}
|
||||
|
||||
if (event.ctrl) {
|
||||
|
||||
@@ -91,6 +91,7 @@ int LuaListBuffers(lua_State *L) {
|
||||
Scratch scratch;
|
||||
Array<String> strings = {scratch};
|
||||
For(Buffers) {
|
||||
if (StartsWith(it.name, "*infobar")) continue;
|
||||
String string = Format(scratch, "%.*s", FmtString(it.name));
|
||||
Add(&strings, string);
|
||||
}
|
||||
@@ -111,6 +112,7 @@ int LuaGetBufferList(lua_State *L) {
|
||||
|
||||
int i = 1;
|
||||
For(Buffers) {
|
||||
if (StartsWith(it.name, "*infobar")) continue;
|
||||
lua_pushinteger(L, i++);
|
||||
lua_pushlstring(L, it.name.data, it.name.len);
|
||||
lua_settable(L, -3); /* 3rd element from the stack top */
|
||||
@@ -215,7 +217,7 @@ Color GetColor(String name, Color default_color) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Buffer *LuaBuffer = NULL;
|
||||
BufferID LuaBufferID = {-1};
|
||||
Int LuaBufferChangeID = 0;
|
||||
void ReloadStyle();
|
||||
extern String BaseLuaConfig;
|
||||
@@ -239,19 +241,23 @@ void ReloadLuaConfig() {
|
||||
SDL_RemovePath(lua_config_path.data);
|
||||
#endif
|
||||
|
||||
LuaBuffer = BufferOpenFile(lua_config_path);
|
||||
if (LuaBuffer->len == 0) {
|
||||
ReplaceText(LuaBuffer, {}, ToString16(scratch, BaseLuaConfig));
|
||||
Buffer *lua_buffer = BufferOpenFile(lua_config_path);
|
||||
if (lua_buffer->len == 0) {
|
||||
ReplaceText(lua_buffer, {}, ToString16(scratch, BaseLuaConfig));
|
||||
}
|
||||
|
||||
// if we loaded from file this should force to read
|
||||
LuaBuffer->change_id = 2;
|
||||
LuaBufferChangeID = 1;
|
||||
lua_buffer->change_id = 2;
|
||||
LuaBufferChangeID = 1;
|
||||
LuaBufferID = lua_buffer->id;
|
||||
}
|
||||
|
||||
if (LuaBuffer->dirty == false && LuaBuffer->change_id != LuaBufferChangeID) {
|
||||
if (LuaBufferID.id == -1) return;
|
||||
|
||||
Buffer *lua_buffer = GetBuffer(LuaBufferID);
|
||||
if (lua_buffer->dirty == false && lua_buffer->change_id != LuaBufferChangeID) {
|
||||
Scratch scratch;
|
||||
String16 string16 = GetString(*LuaBuffer);
|
||||
String16 string16 = GetString(*lua_buffer);
|
||||
String string = ToString(scratch, string16);
|
||||
if (luaL_dostring(LuaState, string.data) == LUA_OK) {
|
||||
if (lua_isstring(LuaState, -1)) {
|
||||
@@ -270,7 +276,7 @@ void ReloadLuaConfig() {
|
||||
ReportWarningf("Failed to load user config! %s", error_message);
|
||||
lua_pop(LuaState, 1);
|
||||
}
|
||||
LuaBufferChangeID = LuaBuffer->change_id;
|
||||
LuaBufferChangeID = lua_buffer->change_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ void InitBuffer(Allocator allocator, Buffer *buffer, String name, Int size = 409
|
||||
buffer->cap = size;
|
||||
buffer->data = AllocArray(allocator, U16, buffer->cap);
|
||||
buffer->line_starts.allocator = allocator;
|
||||
buffer->undo_stack.allocator = allocator;
|
||||
buffer->redo_stack.allocator = allocator;
|
||||
Add(&buffer->line_starts, (Int)0);
|
||||
}
|
||||
|
||||
@@ -85,6 +87,11 @@ Buffer *CreateTempBuffer(Allocator allocator, Int size = 4096) {
|
||||
}
|
||||
|
||||
Window *CreateWindow() {
|
||||
if (Windows.data == NULL) {
|
||||
Reserve(&Windows, 256);
|
||||
}
|
||||
Assert(Windows.len + 1 <= Windows.cap);
|
||||
|
||||
Window *w = Alloc(&Windows);
|
||||
w->visible = true;
|
||||
w->draw_scrollbar = StyleDrawScrollbar;
|
||||
@@ -217,7 +224,7 @@ Buffer *BufferOpenFile(String path) {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
UTF16Result encode = UTF32ToUTF16(decode.out_str);
|
||||
UTF16Result encode = UTF32ToUTF16(u32);
|
||||
if (!encode.error) {
|
||||
for (int64_t encode_i = 0; encode_i < encode.len; encode_i += 1) {
|
||||
buffer->data[buffer->len++] = encode.out_str[encode_i];
|
||||
|
||||
@@ -121,8 +121,8 @@ Event TranslateSDLEvent(SDL_Event *input_event) {
|
||||
} break;
|
||||
|
||||
case SDL_EVENT_MOUSE_MOTION: {
|
||||
event.kind = EVENT_MOUSE_MOVE;
|
||||
SDL_MouseMotionEvent &b = input_event->motion;
|
||||
event.kind = EVENT_MOUSE_MOVE;
|
||||
// SDL_MouseMotionEvent &b = input_event->motion;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
@@ -239,7 +239,6 @@ int main()
|
||||
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
|
||||
const char *glsl_version = "#version 450";
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
@@ -304,9 +303,7 @@ int main()
|
||||
Update(it);
|
||||
}
|
||||
|
||||
WaitForEvents = true;
|
||||
Window *window = GetActiveWindow();
|
||||
View *view = GetView(window->active_view);
|
||||
WaitForEvents = true;
|
||||
if (DocumentSelected || ScrollbarSelected) {
|
||||
WaitForEvents = false;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,6 @@ void ReplaceTitleBarData(Window *window) {
|
||||
Scratch scratch;
|
||||
Caret caret = last_view->carets[0];
|
||||
XY xy = PosToXY(*last_buffer, GetFront(caret));
|
||||
String name = last_buffer->name;
|
||||
|
||||
String16 buffer_string = GetString(*buffer);
|
||||
Range replace_range = {0, buffer->len};
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
- page up and down should also scroll and leave you in exactly same scroll
|
||||
- I think the way sublime text and we display line highlights is confusing with multiple cursors (line highlight can be confused with selection)
|
||||
- ctrl + delete maybe should stop on new line but it keeps on going, sublime is much more careful with deleting
|
||||
BUG: there is a click hang when switching windows sometimes, you click after select and it doesn't switch active window
|
||||
|
||||
- WE CAN'T REALLY NOW USE POINTERS DO WE !!! WE USE DYNAMIC ARRAYS!!
|
||||
|
||||
- mouse execute
|
||||
- alt right click what to do ? (toggle console?)
|
||||
- experiment with using multiple cursors to select command and it's input
|
||||
- should be able click on title bar of windows which disappear on losing focus
|
||||
- console window should close on esacpe but make it more coherent
|
||||
- Ctrl + G should select the line number in bar
|
||||
- consider highlighting different things on alt
|
||||
- search as a command to execute which is going to be in the title bar
|
||||
- each buffer needs a directory even the special ones: C:\a\b\c\+errors?
|
||||
- open directories - resulting in buffer with dir listing and proper buffer name
|
||||
|
||||
@@ -111,7 +111,7 @@ bool ToggleVisibility(Window *window) {
|
||||
}
|
||||
|
||||
void InitWindows(View *null_view) {
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
Allocator sys_allocator = Perm;
|
||||
|
||||
{
|
||||
Window *window = CreateWindow();
|
||||
|
||||
Reference in New Issue
Block a user