Skip to content

Instantly share code, notes, and snippets.

@thebirk
Created November 27, 2020 22:54
Show Gist options
  • Save thebirk/564006ce9f29b818e61a69b0f990815f to your computer and use it in GitHub Desktop.
Save thebirk/564006ce9f29b818e61a69b0f990815f to your computer and use it in GitHub Desktop.
😈
package test
Id :: struct(T: typeid) {
value: int,
}
Asset :: struct {
id: Id(Asset),
name: string,
}
IAssetRepository :: struct {
get_all: proc(self: ^IAssetRepository) -> []Asset,
get: proc(self: ^IAssetRepository, id: Id(Asset)) -> Maybe(Asset),
add: proc(self: ^IAssetRepository, asset: Asset) -> Id(Asset),
remove: proc(self: ^IAssetRepository, id: Id(Asset)),
update: proc(self: ^IAssetRepository, asset: Asset) -> Asset,
}
Asset_Slot :: struct {
used: bool,
asset: Asset,
}
InMemoryAssetRepository :: struct {
using vtable: IAssetRepository,
db: [dynamic]Asset_Slot,
}
InMemoryAssetRepository_vtable :: IAssetRepository{
get_all = proc(self: ^IAssetRepository) -> []Asset {
using repo := cast(^InMemoryAssetRepository) self;
all: [dynamic]Asset;
for v in db {
if v.used do append(&all, v.asset);
}
return all[:];
},
get = proc(self: ^IAssetRepository, id: Id(Asset)) -> Maybe(Asset) {
using repo := cast(^InMemoryAssetRepository) self;
slot := db[id.value];
if !slot.used do return nil;
return slot.asset;
},
add = proc(self: ^IAssetRepository, asset: Asset) -> Id(Asset) {
using repo := cast(^InMemoryAssetRepository) self;
append(&db, Asset_Slot{true, asset});
id := len(db) - 1;
db[id].asset.id = Id(Asset){id};
return Id(Asset){id};
},
remove = proc(self: ^IAssetRepository, id: Id(Asset)) {
using repo := cast(^InMemoryAssetRepository) self;
db[id.value].used = false;
},
update = proc(self: ^IAssetRepository, asset: Asset) -> Asset {
using repo := cast(^InMemoryAssetRepository) self;
db[asset.id.value].asset = asset;
return db[asset.id.value].asset;
},
};
make_dummy_asset_repo :: proc() -> InMemoryAssetRepository {
// other init stuff
return InMemoryAssetRepository{
vtable = InMemoryAssetRepository_vtable
};
}
import "core:fmt"
use_asset_repo :: proc(repo: ^IAssetRepository) {
n := repo->add(Asset{
name = "Test Asset"
});
fmt.println("repo->get(n):", repo->get(n)); // Asset {...}
repo->remove(n);
fmt.println("repo->get(n):", repo->get(n)); // nil
}
main :: proc() {
fmt.println("Hello, world!");
repo := make_dummy_asset_repo();
use_asset_repo(&repo);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment