Avatar

june

@itsjunetime

she/her | rarrnngnghh

gougle . caom really sleepy go bed but insomniat ?? possible to dissociate somuchy you forget the dissociation how to deal with The Situations tin6y kitten sleep like tiny kitten become tyibyt kitten solve problem?? tin7y kitten dot com

hi tumblr! i havent shown off my project here yet so here we go!!

this is fox32, a 32-bit custom architecture and fantasy computer :3

it runs a custom operating system called fox32os, written in fox32's assembly language. its UI and general internal layout are very inspired by classic Mac OS.

the source code for everything can be found here: https://github.com/fox32-arch

we also have an active discord server if you're interested, come say hi!! :3 https://discord.gg/2Tun7FnUZ2

Avatar

would you like to see my fonts also

Avatar

I am always a slut for fonts

Avatar
Avatar

awesome!!!! So, heres a pixel font I'm working on, it's an italic font, with 6px x height (and 5px for a/descenders). planning to have pan latin+greek+cyrillic support

I like that it looks so pretty and readable. It's roughly based on my own italic handwriting:

This one is a humanist/oldstyle variable font I'm working on, and likewise I'm planning to have pan-latin/greek/cyrillic support for it (Don't have images for other opsz/weight right now, I'm on phone)

also planning on having javanese, thai, devanagari, bengali, etc support eventually (dont worry i am familiar with these scripts)

Avatar

so embarrassing when i forget im checking someone's blog and i start scrolling through and liking and reblogging shit as if it's just my dash. it feels like wandering into someone else's apartment and not noticing and making myself lunch

Avatar

reblog if i can wander into your apartment (blog) and make myself lunch (like and reblog as if it's my dash)

Avatar

Java is a trash language that should burn in the parts of hell where hitler is

Rust on the other hand is a bratty lil language that should burn in the parts of hell where queers party

rust structs you can instantiate at compiletime or runtime

i ran into a problem recently where I wanted a struct in rust that I could create at runtime or compile time, but it needed to own data that was traditionally allocated on the heap (String, Vec, etc), and that's not possible to instantiate at compile time. rust has compile-time analogs for those (&'static str, &'static []), but those can't be created at runtime (yes, I know about Box::leak and mem::transmute, but that's evil).

the initial clunky but seemingly rusty solution: enums! Just use something like

StringWrapper { String(String), StaticStr(&'static str) }

but that seemed clunky and would require a lot of destructuring that i wouldn't be the biggest fan of writing (also, yes, this is basically a Cow, but i felt this would be better for visualization)

maybe a wrapper struct around a StringWrapper enum, i thought? that way we can impl Display and such to make it a bit easier on us? no, then we'd still have to do a lot of weird destructuring and such whenever we wanted to try to edit the data in it, and that meant that we could still have an invalid state (have a StaticStr where we expected a String, etc), and we don't want that (also still a problem with a Cow)

what about just making it store a reference? e.g.

struct Person<'f> { name: &'f str, age: usize, // sky's the limit attributes: &'f [&'f str] }

this way, we could create it at compile-time, and it would be a Person<'static>, so it could live forever (as we want). Then we could also create it at runtime. but the caveat is that I want to OWN the data in it - nothing else will be holding onto that name or those attributes, so we can't hold them as references to something else.

the solution (that i just learned about, which is why i'm sharing this): the 'static bound! don't we already have that, you may say? not exactly - here's what I'm talking about

struct Person< S: 'static + AsRef<str>, A: 'static + AsRef<[S]>, > { name: S, age: usize, attributes: A }

this way, we can have both a Person<String, Vec<String>> and Person<&'static str, &'static [&'static str]>, which fulfills all our use cases! the 'static bound binds the parameter itself, as opposed to the 'f bound earlier, which only bound the lifetime of the references (preventing owned data).

and, with the AsRef bounds, we can do something like the following:

impl<S, A> ToOwned for Person<S, A> where S: 'static + AsRef<str>, A: 'static + AsRef<[S]> { fn to_owned(&self) -> Person<String, Vec<String>> { Person { name: self.name.as_ref().to_owned(), age: self.age, attributes: self.attributes.iter() .map(|a| a.as_ref().to_owned()) .collect() } } }

(some of that syntax may be slightly off, but whatever, you get the point) - this'll allow us to easily convert any Person instance to a Person which we can modify easily (since a Person<&'static str, &'static [&'static str]> was probably created at compile-time and is thus immutable)

now, to be fair, we could just remove the 'static bounds and make a struct like the following:

struct Person<S: AsRef<str>, A: AsRef<[S]>> { ... }

and it would work everywhere our old struct (with the 'static bounds) would, and more! isn't that cool?

no! at least, i don't think so. making it impossible to construct invalid states is very important imo, and (in my use of this struct, at least), it would be an invalid state to instantiate this struct with non-'static lifetimes (e.g. where those parameters reference something else). maybe that'll change in the future as the uses of this struct change, but maybe not.

also check out Code and Bitters' article on the same topic, which talks about similar stuff but more in the context of thread spawning and how they ensure lifetime bounds are valid

my specific use-case was in writing a character management system (specifically for the ttrpg HEART: The City Beneath - it's really fun, everyone should check it out), for managing items in the character's inventory/equipment. in this system, there are a lot of classes, and each class has some items you can pick from to put in your inventory when you create a character, and i wanted the list of classes to always be easily accessible in the code so that the user could always view a class if they wanted to reference something about it, or change their class, or make a new character and pick a class, etc.

so there were a few clear options for achieving this goal:

  1. a manager struct of some sort that would manage all the 'reference' data for the system (all the classes, callings, beats, fallout, etc, that comes with the ttrpg system) and would instantiate all that data at runtime - this seemed fine, but would require me to pass the manager struct around to every fn/struct/etc that wanted any data from it at all, and that seemed like it would be really annoying to do.
  2. initializing all that data behind a OnceLock (along with a global wrapper function to ensure I always got valid data when I requested it and didn't have to deal with unwrapping the OnceLock's data) - this seemed slightly more appealing, but also required initializing at runtime, which wasn't ideal, and would require more wrapper functions to handle initialization of each class and calling and such, and a lot of nested structures to store all that data together, and that seemed like more code than i wanted to write as well.
  3. making them all as individual items at compile-time! which is what i ended up doing, of course. that way, i could just put all the classes together into a &'static [] and iterate over them wherever i needed to. no complicated passing around of data, no wrapper initialization functions, no possible twice-initialization, etc. (also technically this would speed up startup, but that effect was probably negligible) however, i did want users to be able to copy items from inside a class into their inventory and edit them however they pleased, and that's how i ran into this problem, and that's why this is the solution i came up with.

so the actual struct i'm working with ended up being like so:

#[derive(Clone)] pub struct Item< S: 'static + AsRef<str>, V: 'static + AsRef<[&'static Tag]> > { pub name: S, pub skill: ItemSkill, pub die: DieLevel, pub tags: V, pub notes: S }

and i implemented the helper function like so:

impl Item<&'static str, &'static [&'static Tag]> { pub fn owned(&self) -> Item<String, Vec<&'static Tag>> { Item { name: self.name.to_owned(), skill: self.skill.clone(), die: self.die, tags: self.tags.to_vec(), notes: self.notes.to_owned() } } }

(i didn't directly impl ToOwned 'cause Clone implicitly impls ToOwned, and i needed Clone for something else, i can't remember)

so now the user can store their class as a &'static Class, (and the class will store the item as an Item<&'static str, &'static [&'static Tag]>) and grab an item from it with just self.inventory.push(self.class.item.owned()) and then edit it to their heart's content! you can also see here how it wouldn't really make sense to have an Item<&'a str, &'a [&'static Tag]> where 'a is not 'static - where would we be referencing data from? the item is supposed to only be owned by the class or character, and thus needs to either be 'static and immutable or owned and mutable, and a non-'static lifetime doesn't fulfill either of those requirements.

i hope that helps, and obviously i love talking about rust so feel free to ask any other questions :)

rust structs you can instantiate at compiletime or runtime

i ran into a problem recently where I wanted a struct in rust that I could create at runtime or compile time, but it needed to own data that was traditionally allocated on the heap (String, Vec, etc), and that's not possible to instantiate at compile time. rust has compile-time analogs for those (&'static str, &'static []), but those can't be created at runtime (yes, I know about Box::leak and mem::transmute, but that's evil).

the initial clunky but seemingly rusty solution: enums! Just use something like

StringWrapper { String(String), StaticStr(&'static str) }

but that seemed clunky and would require a lot of destructuring that i wouldn't be the biggest fan of writing (also, yes, this is basically a Cow, but i felt this would be better for visualization)

maybe a wrapper struct around a StringWrapper enum, i thought? that way we can impl Display and such to make it a bit easier on us? no, then we'd still have to do a lot of weird destructuring and such whenever we wanted to try to edit the data in it, and that meant that we could still have an invalid state (have a StaticStr where we expected a String, etc), and we don't want that (also still a problem with a Cow)

what about just making it store a reference? e.g.

struct Person<'f> { name: &'f str, age: usize, // sky's the limit attributes: &'f [&'f str] }

this way, we could create it at compile-time, and it would be a Person<'static>, so it could live forever (as we want). Then we could also create it at runtime. but the caveat is that I want to OWN the data in it - nothing else will be holding onto that name or those attributes, so we can't hold them as references to something else.

the solution (that i just learned about, which is why i'm sharing this): the 'static bound! don't we already have that, you may say? not exactly - here's what I'm talking about

struct Person< S: 'static + AsRef<str>, A: 'static + AsRef<[S]>, > { name: S, age: usize, attributes: A }

this way, we can have both a Person<String, Vec<String>> and Person<&'static str, &'static [&'static str]>, which fulfills all our use cases! the 'static bound binds the parameter itself, as opposed to the 'f bound earlier, which only bound the lifetime of the references (preventing owned data).

and, with the AsRef bounds, we can do something like the following:

impl<S, A> ToOwned for Person<S, A> where S: 'static + AsRef<str>, A: 'static + AsRef<[S]> { fn to_owned(&self) -> Person<String, Vec<String>> { Person { name: self.name.as_ref().to_owned(), age: self.age, attributes: self.attributes.iter() .map(|a| a.as_ref().to_owned()) .collect() } } }

(some of that syntax may be slightly off, but whatever, you get the point) - this'll allow us to easily convert any Person instance to a Person which we can modify easily (since a Person<&'static str, &'static [&'static str]> was probably created at compile-time and is thus immutable)

now, to be fair, we could just remove the 'static bounds and make a struct like the following:

struct Person<S: AsRef<str>, A: AsRef<[S]>> { ... }

and it would work everywhere our old struct (with the 'static bounds) would, and more! isn't that cool?

no! at least, i don't think so. making it impossible to construct invalid states is very important imo, and (in my use of this struct, at least), it would be an invalid state to instantiate this struct with non-'static lifetimes (e.g. where those parameters reference something else). maybe that'll change in the future as the uses of this struct change, but maybe not.

also check out Code and Bitters' article on the same topic, which talks about similar stuff but more in the context of thread spawning and how they ensure lifetime bounds are valid