<commit_before>#include "core/file.h"
#include "core/malloc.h"
#include "game/world.h"
#include "global/env.h"

/// TEMP
#include "visual/renderer.h"
#include "physics/physworld.h"
#include "resources/resblob.h"

#include <math.h>

internal
T3d temptest_t3d_storage[MAX_NODE_COUNT];
internal
U32 next_t3d= 0;

internal
void * node_impl(U32 *size, NodeInfo *node)
{
	switch (node->type) {
		case NodeType_ModelEntity:
			if (size) *size= sizeof(ModelEntity);
			return &g_env.renderer->entities[node->impl_handle];
		break;
		case NodeType_T3d:
			if (size) *size= sizeof(T3d);
			return &temptest_t3d_storage[node->impl_handle];
		break;
		case NodeType_RigidBody:
			if (size) *size= sizeof(RigidBody);
			return &g_env.phys_world->bodies[node->impl_handle];
		break;
		default:
			fail("node_impl: Unhandled type: %i", node->type);
	}
	return NULL;
}

void upd_t3d_nodes(	World *w,
					T3d *t,
					U32 count)
{
	for (U32 i= 0; i < count; ++i, ++t) {
		int asd= (int)t;
		t->pos.x= sin(asd + w->time*0.7)*3.0;
		t->pos.y= sin(asd*asd + w->time*0.3427)*1.5;
		t->pos.z= sin(asd)*5 + 6;
	}
}

World * create_world()
{
	World *w= zero_malloc(sizeof(*w));
	return w;
}

void destroy_world(World *w)
{
	debug_print("destroy_world: %i nodes", w->node_count);
	for (U32 i= 0; i < MAX_NODE_COUNT; ++i) {
		if (w->nodes[i].allocated)
			free_node(w, i);
	}
	free(w);
}

void upd_world(World *w, F64 dt)
{
	w->time += dt;
	NodeInfo *nodes= w->nodes;

	/// @todo Sorting, update batches
	for (U32 node_i= 0; node_i < MAX_NODE_COUNT; ++node_i) {
		NodeInfo *node= &nodes[node_i];
		if (!node->allocated)
			continue;

		switch (node->type) {
			case NodeType_ModelEntity:
			break;
			case NodeType_T3d:
				upd_t3d_nodes(w, node_impl(NULL, node), 1);
			break;
			case NodeType_RigidBody:
			break;
			default: fail("upd_world: Unhandled type: %i", node->type);
		}

		// Propagate values
		for (U32 r_i= 0; r_i < MAX_NODE_ROUTING_COUNT; ++r_i) {
			if (!node->routing[r_i].allocated)
				continue;

			SlotRouting *r= &node->routing[r_i];
			ensure(r->dst_node < MAX_NODE_COUNT);
			NodeInfo *dst_node= &w->nodes[r->dst_node];

			U8 *dst= (U8*)node_impl(NULL, dst_node) + r->dst_offset;
			U8 *src= (U8*)node_impl(NULL, node) + r->src_offset;
			for (U32 i= 0; i < r->size; ++i)
				dst[i]= src[i];
		}
	}
}

typedef struct {
	U32 version;
	U32 node_count;
} PACKED SaveHeader;

void load_world(World *w, const char *path)
{
	debug_print("load_world: %s", path);
	if (w->node_count > 0) {
		debug_print("load_world: destroying current world");
		for (U32 i= 0; i < MAX_NODE_COUNT; ++i) {
			if (w->nodes[i].allocated)
				free_node(w, i);
		}
	}
	ensure(w->node_count == 0);

	FILE *file= fopen(path, "rb");
	if (!file)
		fail("load_world: Couldn't open: %s", path);

	SaveHeader header;
	int len= fread(&header, 1, sizeof(header), file);
	if (len != sizeof(header))
		fail("load_world: Read error");

	for (U32 i= 0; i < header.node_count; ++i) {
		// Create node from dump

		NodeInfo dead_node;
		fread(&dead_node, 1, sizeof(dead_node), file);

		U32 node_h= alloc_node(w, dead_node.type);
		ensure(node_h == i); // Must retain handles because of routing

		NodeInfo *node= &w->nodes[node_h];
		memcpy(node->routing, dead_node.routing, sizeof(*node->routing));

		switch (dead_node.type) {
			case NodeType_ModelEntity: {
				ModelEntity dead_impl;
				fread(&dead_impl, 1, sizeof(dead_impl), file);
				set_modelentity(
						g_env.renderer,
						node->impl_handle,
						(Model*)res_by_name(
							g_env.res_blob,
							ResType_Model,
							dead_impl.model_name));
				ModelEntity *impl= &g_env.renderer->entities[node->impl_handle];
				impl->pos= dead_impl.pos;
				impl->rot= dead_impl.rot;
			}
			break;
			case NodeType_T3d: {
				T3d dead_impl;
				fread(&dead_impl, 1, sizeof(dead_impl), file);
				T3d *impl= &temptest_t3d_storage[node->impl_handle];
				*impl= dead_impl;
			 }
			break;<commit_msg>Fixed bug in retaining routing<commit_after>#include "core/file.h"
#include "core/malloc.h"
#include "game/world.h"
#include "global/env.h"

/// TEMP
#include "visual/renderer.h"
#include "physics/physworld.h"
#include "resources/resblob.h"

#include <math.h>

internal
T3d temptest_t3d_storage[MAX_NODE_COUNT];
internal
U32 next_t3d= 0;

internal
void * node_impl(U32 *size, NodeInfo *node)
{
	switch (node->type) {
		case NodeType_ModelEntity:
			if (size) *size= sizeof(ModelEntity);
			return &g_env.renderer->entities[node->impl_handle];
		break;
		case NodeType_T3d:
			if (size) *size= sizeof(T3d);
			return &temptest_t3d_storage[node->impl_handle];
		break;
		case NodeType_RigidBody:
			if (size) *size= sizeof(RigidBody);
			return &g_env.phys_world->bodies[node->impl_handle];
		break;
		default:
			fail("node_impl: Unhandled type: %i", node->type);
	}
	return NULL;
}

void upd_t3d_nodes(	World *w,
					T3d *t,
					U32 count)
{
	for (U32 i= 0; i < count; ++i, ++t) {
		int asd= (int)t;
		t->pos.x= sin(asd + w->time*0.7)*3.0;
		t->pos.y= sin(asd*asd + w->time*0.3427)*1.5;
		t->pos.z= sin(asd)*5 + 6;
	}
}

World * create_world()
{
	World *w= zero_malloc(sizeof(*w));
	return w;
}

void destroy_world(World *w)
{
	debug_print("destroy_world: %i nodes", w->node_count);
	for (U32 i= 0; i < MAX_NODE_COUNT; ++i) {
		if (w->nodes[i].allocated)
			free_node(w, i);
	}
	free(w);
}

void upd_world(World *w, F64 dt)
{
	w->time += dt;
	NodeInfo *nodes= w->nodes;

	/// @todo Sorting, update batches
	for (U32 node_i= 0; node_i < MAX_NODE_COUNT; ++node_i) {
		NodeInfo *node= &nodes[node_i];
		if (!node->allocated)
			continue;

		switch (node->type) {
			case NodeType_ModelEntity:
			break;
			case NodeType_T3d:
				upd_t3d_nodes(w, node_impl(NULL, node), 1);
			break;
			case NodeType_RigidBody:
			break;
			default: fail("upd_world: Unhandled type: %i", node->type);
		}

		// Propagate values
		for (U32 r_i= 0; r_i < MAX_NODE_ROUTING_COUNT; ++r_i) {
			if (!node->routing[r_i].allocated)
				continue;

			SlotRouting *r= &node->routing[r_i];
			ensure(r->dst_node < MAX_NODE_COUNT);
			NodeInfo *dst_node= &w->nodes[r->dst_node];

			U8 *dst= (U8*)node_impl(NULL, dst_node) + r->dst_offset;
			U8 *src= (U8*)node_impl(NULL, node) + r->src_offset;
			for (U32 i= 0; i < r->size; ++i)
				dst[i]= src[i];
		}
	}
}

typedef struct {
	U32 version;
	U32 node_count;
} PACKED SaveHeader;

void load_world(World *w, const char *path)
{
	debug_print("load_world: %s", path);
	if (w->node_count > 0) {
		debug_print("load_world: destroying current world");
		for (U32 i= 0; i < MAX_NODE_COUNT; ++i) {
			if (w->nodes[i].allocated)
				free_node(w, i);
		}
	}
	ensure(w->node_count == 0);

	FILE *file= fopen(path, "rb");
	if (!file)
		fail("load_world: Couldn't open: %s", path);

	SaveHeader header;
	int len= fread(&header, 1, sizeof(header), file);
	if (len != sizeof(header))
		fail("load_world: Read error");

	for (U32 i= 0; i < header.node_count; ++i) {
		// Create node from dump

		NodeInfo dead_node;
		fread(&dead_node, 1, sizeof(dead_node), file);

		U32 node_h= alloc_node(w, dead_node.type);
		ensure(node_h == i); // Must retain handles because of routing

		NodeInfo *node= &w->nodes[node_h];
		memcpy(node->routing, dead_node.routing, sizeof(node->routing));

		switch (dead_node.type) {
			case NodeType_ModelEntity: {
				ModelEntity dead_impl;
				fread(&dead_impl, 1, sizeof(dead_impl), file);
				set_modelentity(
						g_env.renderer,
						node->impl_handle,
						(Model*)res_by_name(
							g_env.res_blob,
							ResType_Model,
							dead_impl.model_name));
				ModelEntity *impl= &g_env.renderer->entities[node->impl_handle];
				impl->pos= dead_impl.pos;
				impl->rot= dead_impl.rot;
			}
			break;
			case NodeType_T3d: {
				T3d dead_impl;
				fread(&dead_impl, 1, sizeof(dead_impl), file);
				T3d *impl= &temptest_t3d_storage[node->impl_handle];
				*impl= dead_impl;
			 }
			break;
{'fraction_non_alphanumeric': 0.16441326530612244, 'fraction_numerical': 0.018877551020408164, 'mean_word_length': 3.879278158058494, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1745719', 'n_tokens_mistral': 3677, 'n_tokens_neox': 3239, 'n_words': 691}