How to allocate / "Push" dynamically

Hey!

I've kind of understood the PushArray() thing casey does.

But Let's say we have a OnGameInit() function and OnGameUpdate(), right now im Pushing all my entites in the
Init() function, because if I would push in the update function it would push the memory every frame and
the pile of preallocated memory would
eventually run out.

How would you usually solve this problem and what are common cases for you to dynamically push stuff?

or do you mostly push all your memory in a init() function and manipulate that data in the update() function ?


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
struct GAME_HANDLER
{
	ENTITY *entity_batch;
	u32 entity_batch_count;
	u32 entity_used;
    bool running = true;
    
};


ENTITY *PushEntity(GAME_HANDLER *game, u32 n_entites_to_push)
{
	assert(game->entity_used + n_entites_to_push <= game->entity_batch_count);
    
	ENTITY *entity = 0;
    
	entity = game->entity_batch + game->entity_used;
	game->entity_used += n_entites_to_push ;


	return entity;
}

void OnGameInti(GAME_HANDLER *game)
{
	if(!is_init)
	{
		game->player PushEntity(game, 1);



		is_init = true;
	}
}

void OnGameUpdate(GAME_HANDLER *game)
{

	ENTITY* player = game->player;
	player->pos += player->vel;
       
    // Pushing here would exhaust preallocated memory....
}

int main()
{
    GAME_HANDLER game = {};
	while(game->running)
	{
		OnGameInit(game);
		OnGameUpdate(game);
	}
	return 0;
}

Edited by C_Worm on Reason: Initial post
the trick is to ensure that eventually there is no need to push anymore.

For example by using a freelist to reuse old allocations. When an entity dies/despawns you add its struct to a (intrusive) linked list of dead entities and when a new entity is needed you first pull an entity from that list and reset the state to a newly spawned entity and if the freelist is empty you can push a new entity.

Or by resetting the allocator to a state from before the allocations (freeing everything that was allocated since then)

C_Worm
But Let's say we have a OnGameInit() function and OnGameUpdate(), right now im Pushing all my entites in the Init() function, because if I would push in the update function it would push the memory every frame and the pile of preallocated memory would eventually run out.


I seems that you don't reuse memory each frame. Once you pushed your vertex and index buffers to the GPU (glSubData), you can free your memory because OpenGL does a copy of that data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int main( void ) {
    /* Reserve space for max_command_count per frame,
    and allocate command_data_storage_size to store vertex and index buffer data
    */
    command_buffer_t command = alloc_command( max_command_count, command_data_storage_size );

    while ( game_running ) {
         clear_command_buffer( &command );
         for ( entities ) {
             push_entity( &command, entity );
         }
         render( &command );
         /* The start of the next loop will clear the command buffer so you still have all the memory. */
    }
}