pawengine/object.c
2025-02-24 20:11:51 +01:00

127 lines
4 KiB
C

#include "object.h"
#include "allocator.h"
#include "dynarray.h"
#include "log.h"
#include "register.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define DT_TARGET 0.016
struct Scene *make_scene(struct Vk *vk, struct Register *reg) {
struct Scene *scene = malloc(sizeof(struct Scene));
memset(scene, 0, sizeof(struct Scene));
scene->vk = vk;
scene->mem = make_mem(100000);
if (reg == NULL) {
scene->reg = make_register();
} else {
scene->reg = reg;
}
dyn_array_create_inplace_mem(&scene->objects, scene->mem);
dyn_array_create_inplace_mem(&scene->insert_queue, scene->mem);
dyn_array_create_inplace_mem(&scene->named, scene->mem);
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
scene->msecs = time.tv_sec * 1000000 + time.tv_nsec / 1000;
return scene;
}
void free_scene(struct Scene *scene) {
for (int i = 0; i < scene->objects.count; i++) {
scene->objects.items[i]->type->free(scene, scene->objects.items[i]->data);
mem_free(scene->mem, scene->objects.items[i]);
}
dyn_array_destroy(&scene->objects);
for (int i = 0; i < scene->insert_queue.count; i++) {
scene->insert_queue.items[i]->type->free(
scene, scene->insert_queue.items[i]->data);
mem_free(scene->mem, scene->insert_queue.items[i]);
}
dyn_array_destroy(&scene->insert_queue);
dyn_array_destroy(&scene->named);
uninit_mem(scene->mem);
memset(scene, 0, sizeof(struct Scene));
free(scene);
}
void scene_tick(struct Scene *scene) {
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
long msecs_start = time.tv_sec * 1000000 + time.tv_nsec / 1000;
scene->delta_secs = (float)(msecs_start - scene->msecs) / 1000000;
if (scene->insert_queue.count > 0) {
for (int i = 0; i < scene->insert_queue.count; i++) {
dyn_array_append(&scene->objects, scene->insert_queue.items[i]);
}
scene->insert_queue.count = 0;
}
for (int i = 0; i < scene->objects.count; i++) {
scene->objects.items[i]->type->tick(scene, scene->objects.items[i]->data);
}
if (scene->insert_queue.count > 0) {
for (int i = 0; i < scene->insert_queue.count; i++) {
dyn_array_append(&scene->objects, scene->insert_queue.items[i]);
}
scene->insert_queue.count = 0;
}
clock_gettime(CLOCK_MONOTONIC, &time);
long msecs_end = time.tv_sec * 1000000 + time.tv_nsec / 1000;
struct timespec t = {
.tv_sec = 0,
.tv_nsec =
(((1.0 / 120.0) * 1000000) - (msecs_end - scene->msecs)) * 1000,
};
scene->msecs = msecs_start;
nanosleep(&t, NULL);
meow("dt was %f", scene->delta_secs);
}
void scene_queue_insert(struct Scene *scene, char *name, void *object_data) {
struct Type *type = reg_get_type(scene->reg, name);
struct Object *object = mem_malloc(scene->mem, sizeof(struct Object));
object->type = type;
object->data = object_data;
dyn_array_append(&scene->insert_queue, object);
}
void scene_queue_insert_from_data(struct Scene *scene, char *name, char *data,
int len) {
struct Type *type = reg_get_type(scene->reg, name);
struct Object *object = mem_malloc(scene->mem, sizeof(struct Object));
object->type = type;
object->data = type->make(scene, data, len);
dyn_array_append(&scene->insert_queue, object);
}
void scene_register_named(struct Scene *scene, const char *id,
struct Object *object) {
dyn_array_append(&scene->named, ((struct Named){id, object}));
}
void scene_unregister_named(struct Scene *scene, const char *id) {
for (int i = 0; i < scene->named.count; i++) {
if (strcmp(scene->named.items[i].id, id) == 0) {
dyn_array_remove(&scene->named, i);
return;
}
}
meow("object with name %s was not found", id);
}
struct Object *scene_get_named(struct Scene *scene, const char *id) {
for (int i = 0; i < scene->named.count; i++) {
if (strcmp(scene->named.items[i].id, id) == 0) {
return scene->named.items[i].object;
}
}
meow("object with name %s was not found", id);
return NULL;
}