From: Brendan Hansen Date: Tue, 2 May 2023 03:17:02 +0000 (-0500) Subject: added: titles and favicon X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8fa7a397c4e3731fe57910c486bbe27ae0dd9233;p=onyxlang.io.git added: titles and favicon --- diff --git a/build.onyx b/build.onyx index e56f8a2..09be220 100644 --- a/build.onyx +++ b/build.onyx @@ -1,8 +1,4 @@ -#load "./lib/http-server/module" -#load "./lib/postgres/module" -#load "./lib/postgres-orm/module" -#load "./lib/otmp/module" -#library_path "./bin" +#load "./lib/packages" #load_all "./src" diff --git a/onyx-pkg.ini b/onyx-pkg.ini index 2e4b2e0..9ba7f06 100644 --- a/onyx-pkg.ini +++ b/onyx-pkg.ini @@ -20,6 +20,7 @@ library= git://onyxlang.io/repo/http-server=0.1.26 git://onyxlang.io/repo/postgres-orm=0.0.25 git://onyxlang.io/repo/otmp=0.0.7 +git://onyxlang.io/repo/postgres=0.0.10 [dependency_folders] git://onyxlang.io/repo/http-server=http-server diff --git a/src/app.onyx b/src/app.onyx index 10812c4..ec3d3c3 100644 --- a/src/app.onyx +++ b/src/app.onyx @@ -14,43 +14,45 @@ reg: otmp.TemplateRegistry; #inject Res { render :: (r: &Res, template: str, vars: any) { s := reg->render_template(template, &r.writer, .{ vars.data, vars.type }); + + if s != .None { + log(.Warning, "Template Renderer", tprintf("{}", s)); + } + r->status(200 if s == .None else 400); r->end(); } } @route.{.GET, "/"} -(req: &Req, res: &Res) { - res->render("pages/homepage", null); -} - +(req: &Req, res: &Res) => res->render("pages/homepage", null); @route.{.GET, "/ovmwasm"} -(req: &Req, res: &Res) { - res->render("pages/ovmwasm", null); -} +(req: &Req, res: &Res) => res->render("pages/ovmwasm", null); @route.{.GET, "/docs"} -(req: &Req, res: &Res) { - res->render("pages/docs", null); -} +(req: &Req, res: &Res) => res->render("pages/docs", null); @route.{.GET, "/docs/install"} -(req: &Req, res: &Res) { - res->render("pages/docs/install", null); -} +(req: &Req, res: &Res) => res->render("pages/docs/install", null); + + +Article :: struct { name, description, path, date: str } +news_articles: Cached_Resource([] Article); @route.{.GET, "/news/:article"} (req: &Req, res: &Res) { - // TODO: Safety / error checking here - filename := tprintf("www/news-articles/{}.html", req.url_params["article"]); + article := array.first(news_articles->get() ?? .[], #(it.path == req.url_params["article"])); + if !article do return; + + filename := tprintf("www/news-articles/{}.html", article.path); if os.file_exists(filename) { - article := os.get_contents(filename); - defer delete(&article); + contents := os.get_contents(filename); + defer delete(&contents); res->render("pages/news_article", &.{ - article = article + article = .{ contents = contents, name = article.name } }); } else { @@ -60,17 +62,7 @@ reg: otmp.TemplateRegistry; @route.{.GET, "/news"} (req: &Req, res: &Res) { - Article :: struct { name, description, path, date: str } - articles: [] Article; - - article_file := os.get_contents("www/news-articles/index.json"); - article_index, json_err := json.decode_with_error(article_file); - if json_err->has_error() { - res->status(500); - return; - } - - json.as_any(article_index.root, &articles); + articles := news_articles->get() ?? .[]; res->render("pages/news", &.{ articles = articles @@ -81,6 +73,30 @@ main :: () { reg = otmp.registry(); reg->load_directory("./www/templates", ".html"); + news_articles = .{ + resource = .{}, + max_age = 60 * 60, // 1 hour + + fetch_resource = () -> ? [] Article { + article_file := os.get_contents("www/news-articles/index.json"); + article_index, json_err := json.decode_with_error(article_file); + if json_err->has_error() { + return .{}; + } + + articles: [] Article; + #context_scope { + context.allocator = alloc.heap_allocator; + json.as_any(article_index.root, &articles); + } + return articles; + }, + + release_resource = (articles: &[] Article) { + delete(articles, allocator=alloc.heap_allocator); + } + }; + app := http.server.application(); http.server.set_mime_type("svg", "image/svg+xml"); diff --git a/src/cached_resource.onyx b/src/cached_resource.onyx new file mode 100644 index 0000000..33ad52f --- /dev/null +++ b/src/cached_resource.onyx @@ -0,0 +1,49 @@ +package main + +use core {package, tprintf} +use core.time + +Cached_Resource :: struct (Res: type_expr) { + last_retrieved: time.Timestamp; + max_age: i32; // In seconds + + resource: ? Res; + fetch_resource: () -> ? Res; + release_resource: (res: &Res) -> void; +} + +#inject Cached_Resource { + get :: (use self: &#Self) -> ? self.Res { + if !resource { + update_resource(self); + } + + if time.duration(time.now(), last_retrieved) > max_age { + update_resource(self); + } + + return self.resource; + } +} + +#local +update_resource :: (self: &Cached_Resource($T)) { + if self.resource { + self.release_resource(&self.resource.value); + self.resource->reset(); + } + + self.resource = self.fetch_resource(); + self.last_retrieved = time.now(); +} + + + +#inject time { + duration :: (t2, t1: time.Timestamp) -> i32 { + t1_ := t1; + t2_ := t2; + return ~~(t2_->to_epoch() - t1_->to_epoch()); + } +} + diff --git a/www/news-articles/index.json b/www/news-articles/index.json index 192714a..3a5d45a 100644 --- a/www/news-articles/index.json +++ b/www/news-articles/index.json @@ -1,8 +1,14 @@ [ + { + "name": "Onyx's Memory Model", + "path": "memory_model", + "date": "29th April 2023", + "description": "A explanation of the memory model employed by Onyx." + }, { "name": "Onyx's Custom Runtime", "path": "ovmwasm", "date": "5th April 2023", - "description": "Something about a brief introduction to the OVM-Wasm system." + "description": "A brief introduction to OVM-Wasm, Onyx's custom WASM runtime for debugging and portability." } ] diff --git a/www/news-articles/memory_model.html b/www/news-articles/memory_model.html new file mode 100644 index 0000000..472436a --- /dev/null +++ b/www/news-articles/memory_model.html @@ -0,0 +1,91 @@ +

Onyx's Memory Model

+ +

+When choosing and/or learning a programming language, the memory model is one of the first things you will have to understand to successfully use the language. +In broad terms, there are three memory models employed in programming languages used today: manual, manual with assistance, and automatic. +

+ +

+In a manual memory model, almost all memory allocations and deallocations are done, well, manually. +You, the programmer, are responsible for diligently freeing every piece of memory you allocate; otherwise, over time, your program's memory usage will increase and start consuming a lot of system resources. +

+
+ Do note, that this only applies to programs that run for a long time, or need to work with a lot of resources. + Forgetting to free a 100 element array in your small 10 line program is not going to be the end of the world. + The operating system is responsible for reclaiming all resources your program used when your program exits. +
+ +

+In an automatic memory model, you are not responsible for managing any allocation made by your program. +Programming languages with this memory model generally employ a garbage collector or reference counted pointers. +

+ +

+The third and final memory model is manual with assistance, which is the memory model that Onyx uses. +This model trusts the programmer to understand their memory needs, allowing total control over memory. +However, it also offers core library support for describing the memory model. +

+ +

Allocators

+ +

+Onyx abstracts the notion of memory management into an Allocator. +Anything that requires allocating memory should consume an Allocator as a parameter. +This is the pattern followed by everything in the core library; all memory allocations are configurable. +Also as a convience, the default allocator used by the core library is context.allocator. +This is a thread-local variable that is a general purpose heap allocator by default, but can be changed. +This allows for changing the allocator used by a library even if the library does not take an allocator as a paramter. +

+ +

+Most programmers will not have to write their own allocator. +Instead they will use one of half-dozen provided out of the box by the core libraries. +

+ +

Heap Allocator

+

+In every Onyx program, there is a single general purpose heap allocator. +It can be accessed in core.alloc.heap_allocator. +It is automatically setup before your program reaches main. +It is also the default allocator used by context.allocator, meaning functions like new, make, and calloc will use it by default. +

+ +
+While Onyx has its own heap allocation procedures, the heap allocator is effectively equivalent to C's malloc and free. +You are responsible for manually freeing the memory allocated from it. +
+ +

+Here is an example of using the heap allocator directly. +

+ +
use core {*}
+
+main :: () {
+    // Directly allocate an array of 10 u32's.
+    data := cast([&] u32) alloc.heap_allocator->alloc(sizeof u32 * 10);
+
+    // Ensure the memory is freed when the function returns.
+    defer alloc.heap_allocator->free(data);
+
+    // Fill the array with squares
+    for 10 {
+        data[it] = it * it;
+    }
+
+    // Print out the array
+    for 10 {
+        println(data[it]);
+    }
+}
+
+ + +

Arena Allocator

+ +

+While the general purpose heap allocator will work in any situation, it is not the fastest. +Also, it requires you to correctly manage the memory allocated from it, which can be error prone. +

+ + diff --git a/www/static/css/new_style.css b/www/static/css/new_style.css index 58600cc..b7de5d8 100644 --- a/www/static/css/new_style.css +++ b/www/static/css/new_style.css @@ -111,6 +111,10 @@ h1, h2, h3, h4, h5, h6 { font-weight: 200; } +.container h2 { + margin-top: 16px; +} + .container h3 { margin-top: 12px; } @@ -228,6 +232,13 @@ main pre { display: block; } +main blockquote { + border-left: 4px solid var(--dark-background-color); + background-color: var(--light-background-color); + margin-top: 12px; + padding: 8px; +} + main li { margin-top: 8px; } diff --git a/www/static/images/favicon.ico b/www/static/images/favicon.ico new file mode 100644 index 0000000..dab3947 Binary files /dev/null and b/www/static/images/favicon.ico differ diff --git a/www/templates/pages/404.html b/www/templates/pages/404.html index 42b2056..80dd35e 100644 --- a/www/templates/pages/404.html +++ b/www/templates/pages/404.html @@ -1,3 +1,5 @@ +{{block "title"}}Onyx - Page not found{{endblock}} + {{block "content"}}
diff --git a/www/templates/pages/base.html b/www/templates/pages/base.html index bd60377..2af2bf6 100644 --- a/www/templates/pages/base.html +++ b/www/templates/pages/base.html @@ -7,6 +7,7 @@ + diff --git a/www/templates/pages/docs.html b/www/templates/pages/docs.html index a17d95e..566a4dc 100644 --- a/www/templates/pages/docs.html +++ b/www/templates/pages/docs.html @@ -1,3 +1,5 @@ +{{block "title"}}Onyx Documentation{{endblock}} + {{block "page_content"}}
diff --git a/www/templates/pages/docs/install.html b/www/templates/pages/docs/install.html index e7b0da0..d626fd6 100644 --- a/www/templates/pages/docs/install.html +++ b/www/templates/pages/docs/install.html @@ -1,3 +1,5 @@ +{{block "title"}}Onyx Installation{{endblock}} + {{ block "page_content" }}
diff --git a/www/templates/pages/homepage.html b/www/templates/pages/homepage.html index 222b1b8..2e18fdc 100644 --- a/www/templates/pages/homepage.html +++ b/www/templates/pages/homepage.html @@ -1,3 +1,5 @@ +{{block "title"}}The Onyx Programming Language{{endblock}} + {{block "page_content"}}
diff --git a/www/templates/pages/news.html b/www/templates/pages/news.html index 3ee0613..1f7ba15 100644 --- a/www/templates/pages/news.html +++ b/www/templates/pages/news.html @@ -1,3 +1,5 @@ +{{block "title"}}Onyx News{{endblock}} + {{block "page_content"}}
diff --git a/www/templates/pages/news_article.html b/www/templates/pages/news_article.html index db9362f..a19f0f2 100644 --- a/www/templates/pages/news_article.html +++ b/www/templates/pages/news_article.html @@ -1,10 +1,12 @@ +{{block "title"}}Onyx News - {% $article.name %}{{endblock}} + {{block "content"}}
{% partial "partials/navbar" %}
- {% $article %} + {% $article.contents %}
{% partial "partials/footer" %}