AVXG6N6PW5DPUNPD7S6TSYRXBTJUEEU6G53YMXSDDIH63F252LQAC
#!/bin/bash
workspaceFolder=$(dirname "${BASH_SOURCE[0]}")
pushd "$workspaceFolder"
update_pijul_dep() {
local repo
repo="$1"
local name
name="deps/"$(basename "$2")
# clear the director
rm -rf "$name"
pijul clone "$repo" "$name"
}
mkdir -p deps
# not using this anymore, but keeping it to show how to use the function
# update_pijul_dep https://nest.pijul.com/hardliner66/secs secs
package uuid
import "core:crypto"
import "core:io"
import "core:mem"
UUID_SIZE :: 16
UUID :: distinct [UUID_SIZE]byte
generate :: proc() -> (u: UUID) #no_bounds_check {
crypto.rand_bytes(u[:])
u[6] = (u[6] & 0x0f) | (4 << 4)
u[8] = (u[8] & (0xff >> 2) | (0x02 << 6))
return u
}
to_string :: proc(dst: []byte, u: UUID) #no_bounds_check {
u := u
assert(len(dst) >= 36, "dst not big enough for UUID")
hex(dst[0:8], u[0:4])
dst[8] = '-'
hex(dst[9:13], u[4:6])
dst[13] = '-'
hex(dst[14:18], u[6:8])
dst[18] = '-'
hex(dst[19:23], u[8:10])
dst[23] = '-'
hex(dst[24:], u[10:])
}
clone_to_string :: proc(
u: UUID,
allocator := context.allocator,
) -> (
str: string,
err: mem.Allocator_Error,
) {
buf := make([]byte, 36, allocator) or_return
to_string(buf, u)
str = string(buf)
delete(buf)
return
}
write :: proc(dst: io.Writer, u: UUID, n_written: ^int = nil) -> (int, io.Error) {
buf: [36]byte
to_string(buf[:], u)
return io.write(dst, buf[:], n_written)
}
@(private)
HEXTABLE := [16]byte {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f',
}
@(private)
hex :: proc(dst, src: []byte) #no_bounds_check {
i := 0
for v in src {
dst[i] = HEXTABLE[v >> 4]
dst[i + 1] = HEXTABLE[v & 0x0f]
i += 2
}
}
package main
import "actor"
import "core:c/libc"
import "core:fmt"
MaxMessages :: 10_000_000
Command :: enum {
Inc,
}
stop_behaviour :: proc(
self: ^actor.Actor,
sys: ^actor.System,
state: ^actor.State,
from: actor.ActorRef,
msg: any,
) {
fmt.println("stopping")
actor.stop(sys)
}
counting_behaviour :: proc(
self: ^actor.Actor,
sys: ^actor.System,
state: ^actor.State,
from: actor.ActorRef,
msg: any,
) {
switch d in msg {
case Command:
data := state^.(u128)
switch d {
case .Inc:
data += 1
}
state^ = data
if data >= MaxMessages {
actor.become(self, stop_behaviour)
}
actor.send(sys, self.ref, from, Command.Inc)
case u128:
if d >= MaxMessages {
actor.become(self, stop_behaviour)
}
actor.send(sys, self.ref, from, d + 1)
case string:
fmt.println(d)
}
}
main :: proc() {
sys := actor.new_system()
count := actor.spawn(sys, u128(0), counting_behaviour)
actor.send(sys, count, count, Command.Inc)
actor.work(sys)
actor.destroy_system(sys)
}
package actors
import "../uuid"
Anything :: struct {
data: any,
ptr: rawptr,
}
new_anything :: proc(value: $T) -> Anything {
p := new(T)
p^ = value
return Anything{p^, p}
}
free_anything :: proc(any: Anything) {
free(any.ptr)
}
Any :: union {
// booleans
bool,
b8,
b16,
b32,
b64,
// integers
int,
i8,
i16,
i32,
i64,
i128,
uint,
u8,
u16,
u32,
u64,
u128,
uintptr,
// endian specific integers
// little endian
i16le,
i32le,
i64le,
i128le,
u16le,
u32le,
u64le,
u128le,
// big endian
i16be,
i32be,
i64be,
i128be,
u16be,
u32be,
u64be,
u128be,
// floating point numbers
f16,
f32,
f64,
// endian specific floating point numbers
// little endian
f16le,
f32le,
f64le,
// big endian
f16be,
f32be,
f64be,
// complex numbers
complex32,
complex64,
complex128,
// quaternion numbers
quaternion64,
quaternion128,
quaternion256,
// signed 32 bit integer
// represents a Unicode code point
// is a distinct type to `i32`
rune,
// strings
string,
cstring,
// raw pointer type
rawptr,
// runtime type information specific type
typeid,
// custom types
ActorRef,
// containers
[dynamic]Any,
map[string]Any,
}
State :: Any
Behavior :: proc(self: ^Actor, sys: ^System, state: ^State, from: ActorRef, msg: any)
Actor :: struct {
ref: ActorRef,
behavior: Behavior,
last_behavior: Maybe(Behavior),
state: State,
}
ActorRef :: struct {
addr: string,
}
Message :: struct {
to: ActorRef,
from: ActorRef,
msg: Anything,
}
System :: struct {
actors: map[string]Actor,
queue: [dynamic]Message,
running: bool,
}
new_system :: proc() -> ^System {
sys := new(System)
sys.running = true
sys.actors = make(map[string]Actor)
sys.queue = make([dynamic]Message, 0)
return sys
}
destroy_system :: proc(sys: ^System) {
for len(sys.queue) > 0 {
msg := pop(&sys.queue)
free_anything(msg.msg)
}
delete(sys.queue)
delete(sys.actors)
free(sys)
}
spawn :: proc(sys: ^System, state: State, behavior: Behavior) -> ActorRef {
id := uuid.generate()
id_string, err := uuid.clone_to_string(id)
assert(err == nil)
ref := ActorRef{id_string}
sys.actors[id_string] = Actor{ref, behavior, nil, state}
return ref
}
become :: proc(self: ^Actor, behavior: Behavior) {
self^.last_behavior = self^.behavior
self^.behavior = behavior
}
unbecome :: proc(self: ^Actor) {
if self^.last_behavior != nil {
self^.behavior = self^.last_behavior.?
}
}
send :: proc(sys: ^System, from: ActorRef, to: ActorRef, msg: $T) {
m := new_anything(msg)
append(&sys.queue, Message{to, from, m})
}
stop :: proc(sys: ^System) {
sys.running = false
}
work :: proc(sys: ^System) {
for sys.running {
if len(sys.queue) == 0 {
break
}
msg := pop_front(&sys.queue)
actor := &sys.actors[msg.to.addr]
actor.behavior(actor, sys, &actor.state, msg.from, msg.msg.data)
free_anything(msg.msg)
}
}
{
"$schema": "https://raw.githubusercontent.com/DanielGavin/ols/master/misc/ols.schema.json",
"collections": [
{
"name": "core",
"path": "/usr/lib/odin/core"
}
],
"enable_document_symbols": true,
"enable_semantic_tokens": true,
"enable_hover": true,
"enable_snippets": true
}
#!/bin/bash
workspaceFolder=$(dirname "${BASH_SOURCE[0]}")
odin run "$workspaceFolder/src" -out:${workspaceFolder}/build/abps -debug
#!/bin/bash
workspaceFolder=$(dirname "${BASH_SOURCE[0]}")
odin build "$workspaceFolder/src" -out:${workspaceFolder}/build/abps -o:aggressive
#!/bin/bash
workspaceFolder=$(dirname "${BASH_SOURCE[0]}")
odin build "$workspaceFolder/src" -out:${workspaceFolder}/build/abps -debug
# Actor Based Programming System (ABPS)
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Debug",
"type": "shell",
"command": "odin",
"args": [
"build",
"${workspaceFolder}/src",
"-out:${workspaceFolder}/build/abps",
"-debug"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"problemMatcher": []
}
]
}
{
"python.autoComplete.extraPaths": [
"${workspaceFolder}/sources/poky/bitbake/lib",
"${workspaceFolder}/sources/poky/meta/lib"
],
"python.analysis.extraPaths": [
"${workspaceFolder}/sources/poky/bitbake/lib",
"${workspaceFolder}/sources/poky/meta/lib"
],
"[python]": {
"diffEditor.ignoreTrimWhitespace": false,
"gitlens.codeLens.symbolScopes": [
"!Module"
],
"editor.formatOnType": true,
"editor.wordBasedSuggestions": "off",
"files.trimTrailingWhitespace": false
},
"[shellscript]": {
"files.eol": "\n",
"files.trimTrailingWhitespace": false
}
}
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Odin Project with LLDB",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/build/abps",
"args": [],
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build Debug", // Match the label of your build task in tasks.json
"terminal": "console"
}
]
}
.git
.DS_Store
build
!build/.gitkeep
deps
!deps/.gitkeep
.git
.DS_Store
build
!build/.gitkeep
deps
!deps/.gitkeep