Compare commits
4 Commits
cda805574f
...
46d758c191
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46d758c191 | ||
|
|
b5c9e10477 | ||
|
|
8f4c7745f0 | ||
|
|
b2c3cac73d |
49
build_web.sh
49
build_web.sh
@@ -1,9 +1,46 @@
|
|||||||
#!/usr/bin/bash
|
#!/usr/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
incs="-Isrc/external/SDL/include -Isrc/external/lua/src -Isrc/external/glad -Lsrc/external/SDL/build_web -Isrc"
|
for arg in "$@"; do declare "$arg"='1'; done
|
||||||
wasmflags="-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb -msimd128 -sTOTAL_STACK=5MB -sINITIAL_MEMORY=256mb -sUSE_WEBGL2 -sFULL_ES3=1 -sUSE_SDL=3 -sASYNCIFY -sASSERTIONS=2"
|
if [ ! -v release ]; then debug=1; fi
|
||||||
flags="-Wall -Wno-missing-braces -Wno-writable-strings -nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths"
|
if [ -v debug ]; then echo "[web debug build]"; fi
|
||||||
dbg="-g -DDEBUG_BUILD=1 -gsource-map"
|
if [ -v release ]; then echo "[web release build]"; fi
|
||||||
rel="-O3 -DDEBUG_BUILD=0"
|
|
||||||
|
|
||||||
emcc -o text_editor.html --shell-file=data/shell.html $flags $incs $wasmflags $dbg -lm -lSDL3 src/text_editor/text_editor.cpp
|
# If emsdk is installed but not sourced in this shell, try the common location.
|
||||||
|
if ! command -v emcc >/dev/null 2>&1; then
|
||||||
|
if [ -f "$HOME/emsdk/emsdk_env.sh" ]; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$HOME/emsdk/emsdk_env.sh" >/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v emcc >/dev/null 2>&1; then
|
||||||
|
echo "error: emcc not found. Source emsdk_env.sh or add emcc to PATH." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p build_web
|
||||||
|
|
||||||
|
incs="-Isrc -Isrc/external/glad"
|
||||||
|
flags="-Wall -Wextra -Werror -Wno-error=experimental -Wno-error=unused-parameter -Wformat=2 -Wundef -Wshadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-writable-strings \
|
||||||
|
-fdiagnostics-absolute-paths \
|
||||||
|
-nostdlib++ -fno-exceptions"
|
||||||
|
wasmflags="-sALLOW_MEMORY_GROWTH=0 -sTOTAL_STACK=5MB -sINITIAL_MEMORY=256MB \
|
||||||
|
-sUSE_SDL=3 -sUSE_WEBGL2=1 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -sFULL_ES3=1 \
|
||||||
|
-sASYNCIFY=1 -sASSERTIONS=2 \
|
||||||
|
-sEXIT_RUNTIME=0 \
|
||||||
|
-msimd128"
|
||||||
|
|
||||||
|
if [ -v debug ]; then
|
||||||
|
flags="$flags -g -gsource-map -DDEBUG_BUILD=1"
|
||||||
|
else
|
||||||
|
flags="$flags -O3 -DDEBUG_BUILD=0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
emcc -o build_web/text_editor.html \
|
||||||
|
--shell-file data/shell.html \
|
||||||
|
$flags $incs $wasmflags \
|
||||||
|
src/text_editor.cpp \
|
||||||
|
-lm
|
||||||
|
|
||||||
|
echo "Wrote build_web/text_editor.html"
|
||||||
|
|||||||
76
data/shell.html
Normal file
76
data/shell.html
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no">
|
||||||
|
<title>text_editor</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
outline: none;
|
||||||
|
border: 0;
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
|
||||||
|
<div id="error-box" style="display:none; position:fixed; left:12px; right:12px; bottom:12px; z-index:9999; box-sizing:border-box; max-height:35vh; overflow:auto; padding:10px 12px; border:1px solid #7f1d1d; border-radius:6px; background:rgba(127,29,29,0.94); color:#fff; font:13px/1.35 monospace; white-space:pre-wrap;"></div>
|
||||||
|
<script>
|
||||||
|
const errorBox = document.getElementById('error-box');
|
||||||
|
|
||||||
|
function showError(message) {
|
||||||
|
const text = String(message || 'Unknown error');
|
||||||
|
console.error(text);
|
||||||
|
errorBox.style.display = 'block';
|
||||||
|
errorBox.textContent = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('error', (event) => {
|
||||||
|
showError(event.error && event.error.stack ? event.error.stack : event.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('unhandledrejection', (event) => {
|
||||||
|
const reason = event.reason;
|
||||||
|
showError(reason && reason.stack ? reason.stack : reason);
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
var Module = {
|
||||||
|
canvas: document.getElementById('canvas'),
|
||||||
|
print: (text) => console.log(text),
|
||||||
|
printErr: (text) => showError(text),
|
||||||
|
onAbort: (what) => showError('Aborted: ' + what),
|
||||||
|
setStatus: (text) => { if (text) console.log(text); }
|
||||||
|
};
|
||||||
|
|
||||||
|
function resizeCanvasToDisplaySize() {
|
||||||
|
const canvas = Module.canvas;
|
||||||
|
const dpr = window.devicePixelRatio || 1;
|
||||||
|
const w = Math.max(1, Math.floor(window.innerWidth * dpr));
|
||||||
|
const h = Math.max(1, Math.floor(window.innerHeight * dpr));
|
||||||
|
if (canvas.width !== w || canvas.height !== h) {
|
||||||
|
canvas.width = w;
|
||||||
|
canvas.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', resizeCanvasToDisplaySize);
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
resizeCanvasToDisplaySize();
|
||||||
|
Module.canvas.focus();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{{{ SCRIPT }}}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -331,7 +331,34 @@ API void *BlockArenaAllocatorProc(void *object, int kind, void *p, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
|
BlockArena ScratchArenas[4];
|
||||||
API void InitScratch() {
|
API void InitScratch() {
|
||||||
|
for (int i = 0; i < 4; i += 1) {
|
||||||
|
if (!ScratchArenas[i].blocks) Init(&ScratchArenas[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
API BlockArena *GetScratchEx(BlockArena **conflicts, int conflict_count) {
|
||||||
|
BlockArena *unoccupied = 0;
|
||||||
|
for (int i = 0; i < Lengthof(ScratchArenas); i += 1) {
|
||||||
|
BlockArena *from_pool = &ScratchArenas[i];
|
||||||
|
unoccupied = from_pool;
|
||||||
|
for (int conflict_i = 0; conflict_i < conflict_count; conflict_i += 1) {
|
||||||
|
BlockArena *from_conflict = conflicts[conflict_i];
|
||||||
|
if (from_pool == from_conflict) {
|
||||||
|
unoccupied = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unoccupied) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to get free scratch memory, this is a fatal error, this shouldnt happen
|
||||||
|
Assert(unoccupied);
|
||||||
|
return unoccupied;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
thread_local VirtualArena ScratchArenas[4];
|
thread_local VirtualArena ScratchArenas[4];
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct BlockArena {
|
|||||||
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
API void Init(BlockArena *arena);
|
||||||
API void *PushSize(BlockArena *arena, size_t size);
|
API void *PushSize(BlockArena *arena, size_t size);
|
||||||
API void Release(BlockArena *arena);
|
API void Release(BlockArena *arena);
|
||||||
API void Unwind(BlockArena *arena, U8 *pos);
|
API void Unwind(BlockArena *arena, U8 *pos);
|
||||||
@@ -98,16 +99,43 @@ API void Release(VirtualArena *arena);
|
|||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Scratch
|
// Scratch
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
|
extern BlockArena ScratchArenas[4];
|
||||||
|
API BlockArena *GetScratchEx(BlockArena **conflicts, int conflict_count);
|
||||||
struct Scratch {
|
struct Scratch {
|
||||||
BlockArena arena = {};
|
BlockArena *arena;
|
||||||
Scratch() {}
|
U8 *p;
|
||||||
Scratch(BlockArena *conflict) {}
|
Scratch() {arena = &ScratchArenas[0]; if (!arena->blocks) Init(arena); p = arena->start; arena->refs += 1;}
|
||||||
Scratch(BlockArena *c1, BlockArena *c2) {}
|
Scratch(BlockArena *conflict) {
|
||||||
Scratch(Allocator conflict) {}
|
BlockArena *conf[] = {conflict};
|
||||||
Scratch(Allocator c1, Allocator c2) {}
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
~Scratch() { Release(&arena); }
|
if (!arena->blocks) Init(arena);
|
||||||
operator BlockArena *() { return &arena; }
|
p = arena->start;
|
||||||
operator Allocator() { return arena; }
|
arena->refs += 1;
|
||||||
|
}
|
||||||
|
Scratch(BlockArena *c1, BlockArena *c2) {
|
||||||
|
BlockArena *conf[] = {c1, c2};
|
||||||
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
|
if (!arena->blocks) Init(arena);
|
||||||
|
p = arena->start;
|
||||||
|
arena->refs += 1;
|
||||||
|
}
|
||||||
|
Scratch(Allocator conflict) {
|
||||||
|
BlockArena *conf[] = {(BlockArena *)conflict.object};
|
||||||
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
|
if (!arena->blocks) Init(arena);
|
||||||
|
p = arena->start;
|
||||||
|
arena->refs += 1;
|
||||||
|
}
|
||||||
|
Scratch(Allocator c1, Allocator c2) {
|
||||||
|
BlockArena *conf[] = {(BlockArena *)c1.object, (BlockArena *)c2.object};
|
||||||
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
|
if (!arena->blocks) Init(arena);
|
||||||
|
p = arena->start;
|
||||||
|
arena->refs += 1;
|
||||||
|
}
|
||||||
|
~Scratch() { Unwind(arena, p); arena->refs -= 1; }
|
||||||
|
operator BlockArena *() { return arena; }
|
||||||
|
operator Allocator() { return *arena; }
|
||||||
private: // @Note: Disable copy constructors, cause its error prone
|
private: // @Note: Disable copy constructors, cause its error prone
|
||||||
Scratch(Scratch &arena);
|
Scratch(Scratch &arena);
|
||||||
Scratch(Scratch &arena, Scratch &a2);
|
Scratch(Scratch &arena, Scratch &a2);
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ void IndentedNewLine(View *view) {
|
|||||||
For(view->carets) {
|
For(view->carets) {
|
||||||
Int front = GetFront(it);
|
Int front = GetFront(it);
|
||||||
Int indent = GetLineIndent(buffer, PosToLine(buffer, front));
|
Int indent = GetLineIndent(buffer, PosToLine(buffer, front));
|
||||||
String string = Format(scratch, "\n%.*s", indent, " ");
|
String string = Format(scratch, "\n%.*s", (int)indent, " ");
|
||||||
String16 string16 = ToString16(scratch, string);
|
String16 string16 = ToString16(scratch, string);
|
||||||
AddEdit(&edits, it.range, string16);
|
AddEdit(&edits, it.range, string16);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user