Skip to content

Instantly share code, notes, and snippets.

@nandakoryaaa
Created June 23, 2025 11:00
Show Gist options
  • Select an option

  • Save nandakoryaaa/85b39a678d59cb6e089d91a4483b70ce to your computer and use it in GitHub Desktop.

Select an option

Save nandakoryaaa/85b39a678d59cb6e089d91a4483b70ce to your computer and use it in GitHub Desktop.

Revisions

  1. nandakoryaaa created this gist Jun 23, 2025.
    234 changes: 234 additions & 0 deletions main.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,234 @@
    #[derive (Copy, Clone)]
    struct Rect {
    w: u32,
    h: i32
    }

    struct Renderer {
    canvas: u32 // not used
    }

    impl Renderer {
    fn drawBitmap(&mut self, handle: u32) {
    println!("drawing Bitmap {}", handle);
    }

    fn drawRect(&mut self, rect: Rect) {
    println!("drawing Rect {}x{}", rect.w, rect.h);
    }
    }

    trait Drawable {
    fn draw(&self, renderer: &mut Renderer);
    }

    struct DrawableBitmap {
    handle: u32
    }

    struct DrawableRect {
    rect: Rect
    }

    impl Drawable for DrawableBitmap {
    fn draw(&self, renderer: &mut Renderer) {
    renderer.drawBitmap(self.handle);
    }
    }

    impl Drawable for DrawableRect {
    fn draw(&self, renderer: &mut Renderer) {
    renderer.drawRect(self.rect);
    }
    }

    trait Behaviour {
    fn update(&mut self, gmo_data: &mut GMOData);
    }

    struct BehaviourMove {
    speed: i32
    }

    struct BehaviourWait {
    count: i32
    }

    impl Behaviour for BehaviourMove {
    fn update(&mut self, gmo_data: &mut GMOData) {
    gmo_data.x += self.speed;
    println!("behaviour: Speed {}", gmo_data.x);
    }
    }

    impl Behaviour for BehaviourWait {
    fn update(&mut self, gmo_data: &mut GMOData) {
    self.count += 1;
    println!("behaviour: Wait {}", self.count);
    }
    }

    #[derive (Copy, Clone)]
    struct StageObject<'a> {
    x: i32,
    y: i32,
    drawable: &'a dyn Drawable,
    }

    struct GMOData {
    x: i32,
    y: i32
    }

    struct GameObject<'a> {
    data: GMOData,
    sto_index: usize,
    behaviour: &'a mut dyn Behaviour
    }

    struct STOEntry<'a> {
    prev: usize,
    next: usize,
    sto: StageObject<'a>
    }

    struct STOList<'a> {
    used_list: Vec<STOEntry<'a>>,
    free_list: Vec<usize>,
    capacity: usize,
    cnt: usize,
    first: usize,
    last: usize
    }

    impl<'a> STOList<'a> {
    fn create(capacity: usize) -> Self {
    STOList {
    used_list: Vec::with_capacity(capacity),
    free_list: Vec::with_capacity(capacity),
    capacity: capacity,
    cnt: 0,
    first: 0,
    last: 0
    }
    }

    fn add(&mut self, sto: StageObject<'a>) -> usize {
    let mut index: usize = self.used_list.len();

    let mut stoe = STOEntry {
    prev: self.last,
    next: index,
    sto: sto
    };

    if self.free_list.len() == 0 {
    if (index >= self.capacity) {
    return index;
    }
    self.used_list.push(stoe);
    } else {
    if let Some(val) = self.free_list.pop() {
    index = val;
    stoe.next = index;
    self.used_list[index] = stoe;
    }
    }

    self.used_list[self.last].next = index;
    self.last = index;
    self.cnt += 1;

    index
    }

    fn del(&mut self, index: usize) {
    if index >= self.used_list.len() {
    return;
    }
    let prev = self.used_list[index].prev;
    let next = self.used_list[index].next;

    if index == self.first {
    self.first = next;
    } else {
    self.used_list[prev].next = next;
    }
    if index == self.last {
    self.last = prev;
    } else {
    self.used_list[next].prev = prev;
    }
    self.free_list.push(index);
    self.cnt -= 1;
    }

    }

    struct Stage<'a> {
    w: u32,
    h: u32,
    sto_list: STOList<'a>
    }

    impl<'a> Stage<'a> {
    fn add_child(&mut self, sto: StageObject<'a>) -> usize {
    return self.sto_list.add(sto);
    }

    fn remove_child(&mut self, index: usize) {
    self.sto_list.del(index);
    }

    fn draw(&self, renderer: &mut Renderer) {
    if self.sto_list.cnt == 0 {
    return;
    }
    let mut index = self.sto_list.first;
    while (true) {
    let sto = self.sto_list.used_list[index].sto;
    sto.drawable.draw(renderer);
    if index == self.sto_list.last {
    break;
    }
    index = self.sto_list.used_list[index].next;
    }
    }
    }

    fn process_game_objects(game_objects: &mut [GameObject]) {
    for gmo in game_objects.iter_mut() {
    gmo.behaviour.update(&mut gmo.data);
    }
    }

    pub fn main()
    {
    let mut renderer = Renderer { canvas: 0 /* not used */};
    // testing Stage
    let mut stage = Stage {
    w: 800,
    h: 600,
    sto_list: STOList::create(128)
    };

    let sto_bitmap = stage.add_child(
    StageObject { x: 0, y: 0, drawable: &DrawableBitmap { handle: 5 }}
    );

    let sto_rect = stage.add_child(
    StageObject { x: 0, y: 0, drawable: &DrawableRect { rect: Rect { w:10, h:10 }}}
    );

    stage.draw(&mut renderer);

    // testing game objects
    let mut game_objects: [GameObject; 2] = [
    GameObject { data: GMOData { x: 0, y: 0}, sto_index: sto_bitmap, behaviour: &mut BehaviourMove { speed: 10 } },
    GameObject { data: GMOData { x: 0, y: 0}, sto_index: sto_rect, behaviour: &mut BehaviourWait { count: 0 } }
    ];

    process_game_objects(
    &mut game_objects
    );
    }