From 8fa7a397c4e3731fe57910c486bbe27ae0dd9233 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 1 May 2023 22:17:02 -0500 Subject: [PATCH] added: titles and favicon --- build.onyx | 6 +- onyx-pkg.ini | 1 + src/app.onyx | 74 +++++++++++++-------- src/cached_resource.onyx | 49 ++++++++++++++ www/news-articles/index.json | 8 ++- www/news-articles/memory_model.html | 91 ++++++++++++++++++++++++++ www/static/css/new_style.css | 11 ++++ www/static/images/favicon.ico | Bin 0 -> 4677 bytes www/templates/pages/404.html | 2 + www/templates/pages/base.html | 1 + www/templates/pages/docs.html | 2 + www/templates/pages/docs/install.html | 2 + www/templates/pages/homepage.html | 2 + www/templates/pages/news.html | 2 + www/templates/pages/news_article.html | 4 +- 15 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 src/cached_resource.onyx create mode 100644 www/news-articles/memory_model.html create mode 100644 www/static/images/favicon.ico 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 0000000000000000000000000000000000000000..dab3947ea6e06c691a869b9177e8ee718c379c9e GIT binary patch literal 4677 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 literal 0 HcmV?d00001 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" %} -- 2.25.1