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