]> git.lizzy.rs Git - nothing.git/blob - src/lt.c
(#110) Implement player_checkpoint
[nothing.git] / src / lt.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include "./error.h"
5 #include "./lt.h"
6 #include "./lt/lt_slot.h"
7
8 #define INITIAL_FRAME_BUFFER_SIZE 16
9
10 struct lt_t
11 {
12     lt_slot_t **frames;
13     size_t capacity;
14     size_t size;
15 };
16
17 lt_t *create_lt()
18 {
19     lt_t *lt = malloc(sizeof(lt_t));
20     if(lt == NULL) {
21         throw_error(ERROR_TYPE_LIBC);
22         goto malloc_lt_fail;
23     }
24
25     lt->frames = malloc(sizeof(lt_slot_t*) * INITIAL_FRAME_BUFFER_SIZE);
26     if (lt->frames == NULL) {
27         throw_error(ERROR_TYPE_LIBC);
28         goto malloc_lt_slots_fail;
29     }
30
31     lt->capacity = INITIAL_FRAME_BUFFER_SIZE;
32     lt->size = 0;
33
34     return lt;
35
36 malloc_lt_slots_fail:
37     free(lt);
38 malloc_lt_fail:
39     return NULL;
40 }
41
42 void destroy_lt(lt_t *lt)
43 {
44     assert(lt);
45
46     while (lt->size-- > 0) {
47         if (lt->frames[lt->size]) {
48             destroy_lt_slot(lt->frames[lt->size]);
49         }
50     }
51
52     free(lt->frames);
53     free(lt);
54 }
55
56 void *lt_push(lt_t *lt, void *resource, lt_destroy_t resource_destroy)
57 {
58     assert(lt);
59     assert(resource_destroy);
60     assert(lt != resource);
61
62     if (resource == NULL) {
63         return NULL;
64     }
65
66     if (lt->size >= lt->capacity) {
67         lt->capacity *= 2;
68         if ((lt->frames = realloc(lt->frames, sizeof(lt_slot_t*) * lt->capacity)) == NULL) {
69             throw_error(ERROR_TYPE_LIBC);
70             return NULL;
71         }
72     }
73
74     if ((lt->frames[lt->size++] = create_lt_slot(resource, resource_destroy)) == NULL) {
75         return NULL;
76     }
77
78     return resource;
79 }
80
81 void* lt_reset(lt_t *lt, void *old_resource, void *new_resource)
82 {
83     assert(lt);
84     assert(old_resource);
85     assert(new_resource);
86     assert(old_resource != new_resource);
87
88     for (size_t i = 0; i < lt->size; ++i) {
89         if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], old_resource)) {
90             lt_slot_reset_resource(lt->frames[i], new_resource);
91             return new_resource;
92         }
93     }
94
95     return old_resource;
96 }
97
98 void *lt_release(lt_t *lt, void *resource)
99 {
100     assert(lt);
101     assert(resource);
102
103     for (size_t i = 0; i < lt->size; ++i) {
104         if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], resource)) {
105             release_lt_slot(lt->frames[i]);
106             lt->frames[i] = NULL;
107             return resource;
108         }
109     }
110
111     return resource;
112 }