8/4/26 18:34
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
*.exe
|
||||||
|
/bin
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "submodules/odin-http"]
|
||||||
|
path = submodules/odin-http
|
||||||
|
url = https://github.com/laytan/odin-http.git
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
param(
|
||||||
|
[ValidateSet("run","build","debug","test","clean")]
|
||||||
|
[string]$Command = "build"
|
||||||
|
)
|
||||||
|
|
||||||
|
$src = "."
|
||||||
|
$out = "bin\server.exe"
|
||||||
|
|
||||||
|
switch ($Command) {
|
||||||
|
"run" { odin run $src }
|
||||||
|
"build" { odin build $src -out:$out -o:speed }
|
||||||
|
"debug" { odin build $src -out:$out -debug }
|
||||||
|
"test" { odin test .\tests\ -all-packages }
|
||||||
|
"clean" { Remove-Item -Recurse -Force bin -ErrorAction SilentlyContinue }
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package pheynnx
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/DanielGavin/ols/master/misc/ols.schema.json",
|
||||||
|
"enable_document_symbols": true,
|
||||||
|
"enable_hover": true,
|
||||||
|
"enable_snippets": true
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package pheynnx
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
package pheynnx
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:log"
|
||||||
|
import "core:net"
|
||||||
|
import "core:os"
|
||||||
|
import "core:path/filepath"
|
||||||
|
import "core:strings"
|
||||||
|
import http "submodules/odin-http"
|
||||||
|
|
||||||
|
State :: struct {
|
||||||
|
num: int,
|
||||||
|
global_css: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
state := State {
|
||||||
|
num = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
context.logger = log.create_console_logger(.Info)
|
||||||
|
|
||||||
|
data, err2 := os.read_entire_file_from_path("styles/main.css", context.temp_allocator)
|
||||||
|
state.global_css = string(data)
|
||||||
|
|
||||||
|
s: http.Server
|
||||||
|
http.server_shutdown_on_interrupt(&s)
|
||||||
|
|
||||||
|
router: http.Router
|
||||||
|
http.router_init(&router)
|
||||||
|
defer http.router_destroy(&router)
|
||||||
|
|
||||||
|
root_routes(&router)
|
||||||
|
|
||||||
|
http.route_get(&router, "/static/(.*)", proc() -> http.Handler {
|
||||||
|
return http.Handler {
|
||||||
|
handle = proc(handler: ^http.Handler, req: ^http.Request, res: ^http.Response) {
|
||||||
|
rel_path := strings.trim_prefix(req.url.path, "/static/")
|
||||||
|
full_path, _ := filepath.join({"web/static", rel_path})
|
||||||
|
defer delete(full_path)
|
||||||
|
|
||||||
|
info, err := os.stat(full_path, context.temp_allocator)
|
||||||
|
if err != os.ERROR_NONE || info.type == .Directory {
|
||||||
|
http.respond(res, http.Status.Not_Found)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.respond_dir(res, "/static/", "web/static", req.url.path)
|
||||||
|
|
||||||
|
free_all(context.temp_allocator)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
}())
|
||||||
|
|
||||||
|
routed := http.router_handler(&router)
|
||||||
|
|
||||||
|
err := http.listen_and_serve(&s, routed, net.Endpoint{address = net.IP4_Loopback, port = 6969})
|
||||||
|
fmt.assertf(err == nil, "server stopped with error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROUTERS
|
||||||
|
root_routes :: proc(r: ^http.Router) {
|
||||||
|
http.route_get(r, "/one", one_handler())
|
||||||
|
http.route_get(r, "/two", http.handler(two_handler))
|
||||||
|
}
|
||||||
|
|
||||||
|
// HANDLERS
|
||||||
|
one_handler :: proc() -> http.Handler {
|
||||||
|
return http.Handler {
|
||||||
|
handle = proc(handler: ^http.Handler, req: ^http.Request, res: ^http.Response) {
|
||||||
|
state.num += 1
|
||||||
|
http.respond_html(res, render_index_page(&state))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
two_handler :: proc(req: ^http.Request, res: ^http.Response) {
|
||||||
|
state.num *= 2
|
||||||
|
http.respond_html(res, render_index_page(&state))
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
html {
|
||||||
|
background-color: black;
|
||||||
|
color: wheat;
|
||||||
|
font-family: "Inter", "Helvetica", ui-sans-serif, system-ui, sans-serif,
|
||||||
|
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter";
|
||||||
|
font-weight: normal;
|
||||||
|
src: url("/static/fonts/InterVariable.woff2") format("woff2");
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 100 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "GeistMono";
|
||||||
|
font-display: swap;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
src: url("/static/fonts/GeistMono.ttf");
|
||||||
|
}
|
||||||
Submodule
+1
Submodule submodules/odin-http added at 65f57ca5ed
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package pheynnx
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strings"
|
||||||
|
|
||||||
|
render_index_page :: proc(s: ^State) -> string {
|
||||||
|
b: strings.Builder
|
||||||
|
strings.builder_init(&b)
|
||||||
|
defer strings.builder_destroy(&b)
|
||||||
|
|
||||||
|
strings.write_string(
|
||||||
|
&b,
|
||||||
|
`<!DOCTYPE html><html><head>
|
||||||
|
<title>My Blog</title>
|
||||||
|
<link rel="preload" href="/static/fonts/InterVariable.woff2" as="font" crossorigin/>
|
||||||
|
<link rel="preload" href="/static/fonts/GeistMono.ttf" as="font" crossorigin/>`,
|
||||||
|
)
|
||||||
|
fmt.sbprintf(&b, `<style>%v</style>`, state.global_css)
|
||||||
|
strings.write_string(&b, `</head><body>
|
||||||
|
<main id="content">
|
||||||
|
<h1>Hello!</h1>`)
|
||||||
|
fmt.sbprintf(&b, `<h2>%v</h2>`, state.num)
|
||||||
|
strings.write_string(&b, `</main></body></html>`)
|
||||||
|
|
||||||
|
return strings.clone(strings.to_string(b))
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
console.log("WEHA!");
|
||||||
Reference in New Issue
Block a user