sdis_medium.c (5687B)
1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "sdis.h" 17 #include "sdis_device_c.h" 18 #include "sdis_log.h" 19 #include "sdis_medium_c.h" 20 21 #include <rsys/mem_allocator.h> 22 23 /******************************************************************************* 24 * Helper functions 25 ******************************************************************************/ 26 static res_T 27 check_fluid_shader(const struct sdis_fluid_shader* shader) 28 { 29 if(!shader 30 || !shader->calorific_capacity 31 || !shader->volumic_mass 32 || !shader->temperature) 33 return RES_BAD_ARG; 34 35 return RES_OK; 36 } 37 38 static res_T 39 check_solid_shader(const struct sdis_solid_shader* shader) 40 { 41 if(!shader 42 || !shader->calorific_capacity 43 || !shader->thermal_conductivity 44 || !shader->volumic_mass 45 || !shader->delta 46 || !shader->temperature) 47 return RES_BAD_ARG; 48 49 return RES_OK; 50 } 51 52 static res_T 53 medium_create 54 (struct sdis_device* dev, 55 struct sdis_medium** out_medium, 56 const enum sdis_medium_type type) 57 { 58 struct sdis_medium* medium = NULL; 59 res_T res = RES_OK; 60 61 if(!dev || !out_medium || (unsigned)type >= SDIS_MEDIUM_TYPES_COUNT__) { 62 res = RES_BAD_ARG; 63 goto error; 64 } 65 medium = MEM_CALLOC(dev->allocator, 1, sizeof(struct sdis_medium)); 66 if(!medium) { 67 res = RES_MEM_ERR; 68 goto error; 69 } 70 ref_init(&medium->ref); 71 SDIS(device_ref_get(dev)); 72 medium->dev = dev; 73 medium->type = type; 74 medium->id = flist_name_add(&dev->media_names); 75 flist_name_get(&dev->media_names, medium->id)->mem = medium; 76 77 exit: 78 if(out_medium) *out_medium = medium; 79 return res; 80 error: 81 if(medium) { 82 SDIS(medium_ref_put(medium)); 83 medium = NULL; 84 } 85 goto exit; 86 } 87 88 static void 89 medium_release(ref_T* ref) 90 { 91 struct sdis_medium* medium = NULL; 92 struct sdis_device* dev = NULL; 93 ASSERT(ref); 94 medium = CONTAINER_OF(ref, struct sdis_medium, ref); 95 dev = medium->dev; 96 if(medium->data) SDIS(data_ref_put(medium->data)); 97 flist_name_del(&dev->media_names, medium->id); 98 MEM_RM(dev->allocator, medium); 99 SDIS(device_ref_put(dev)); 100 } 101 102 /******************************************************************************* 103 * Exported functions 104 ******************************************************************************/ 105 res_T 106 sdis_fluid_create 107 (struct sdis_device* dev, 108 const struct sdis_fluid_shader* shader, 109 struct sdis_data* data, /* May be NULL */ 110 struct sdis_medium** out_medium) 111 { 112 struct sdis_medium* medium = NULL; 113 res_T res = RES_OK; 114 115 if(!dev || !out_medium) { res = RES_BAD_ARG; goto error; } 116 117 res = check_fluid_shader(shader); 118 if(res != RES_OK) { 119 log_err(dev, "%s: invalid fluid shader.\n", FUNC_NAME); 120 goto error; 121 } 122 123 res = medium_create(dev, &medium, SDIS_FLUID); 124 if(res != RES_OK) { 125 log_err(dev, "%s: could not create the fluid medium.\n", FUNC_NAME); 126 goto error; 127 } 128 129 if(data) { 130 SDIS(data_ref_get(data)); 131 medium->data = data; 132 } 133 134 medium->shader.fluid = *shader; 135 136 exit: 137 if(out_medium) *out_medium = medium; 138 return res; 139 error: 140 if(medium) { 141 SDIS(medium_ref_put(medium)); 142 medium = NULL; 143 } 144 goto exit; 145 } 146 147 res_T 148 sdis_fluid_get_shader 149 (const struct sdis_medium* mdm, struct sdis_fluid_shader* shader) 150 { 151 if(!mdm || mdm->type != SDIS_FLUID || !shader) return RES_BAD_ARG; 152 *shader = mdm->shader.fluid; 153 return RES_OK; 154 } 155 156 res_T 157 sdis_solid_create 158 (struct sdis_device* dev, 159 const struct sdis_solid_shader* shader, 160 struct sdis_data* data, /* May be NULL */ 161 struct sdis_medium** out_medium) 162 { 163 struct sdis_medium* medium = NULL; 164 res_T res = RES_OK; 165 166 if(!dev || !out_medium) { res = RES_BAD_ARG; goto error; } 167 168 res = check_solid_shader(shader); 169 if(res != RES_OK) { 170 log_err(dev, "%s: invalid solid shader.\n", FUNC_NAME); 171 goto error; 172 } 173 174 res = medium_create(dev, &medium, SDIS_SOLID); 175 if(res != RES_OK) { 176 log_err(dev, "%s: could not create the solid medium.\n", FUNC_NAME); 177 goto error; 178 } 179 180 if(data) { 181 SDIS(data_ref_get(data)); 182 medium->data = data; 183 } 184 185 medium->shader.solid = *shader; 186 187 exit: 188 if(out_medium) *out_medium = medium; 189 return res; 190 error: 191 if(medium) { 192 SDIS(medium_ref_put(medium)); 193 medium = NULL; 194 } 195 goto exit; 196 } 197 198 res_T 199 sdis_solid_get_shader 200 (const struct sdis_medium* mdm, struct sdis_solid_shader* shader) 201 { 202 if(!mdm || mdm->type != SDIS_SOLID || !shader) return RES_BAD_ARG; 203 *shader = mdm->shader.solid; 204 return RES_OK; 205 } 206 207 res_T 208 sdis_medium_ref_get(struct sdis_medium* medium) 209 { 210 if(!medium) return RES_BAD_ARG; 211 ref_get(&medium->ref); 212 return RES_OK; 213 } 214 215 res_T 216 sdis_medium_ref_put(struct sdis_medium* medium) 217 { 218 if(!medium) return RES_BAD_ARG; 219 ref_put(&medium->ref, medium_release); 220 return RES_OK; 221 } 222 223 enum sdis_medium_type 224 sdis_medium_get_type(const struct sdis_medium* medium) 225 { 226 ASSERT(medium != NULL); 227 return medium->type; 228 } 229 230 struct sdis_data* 231 sdis_medium_get_data(struct sdis_medium* medium) 232 { 233 ASSERT(medium); 234 return medium->data; 235 } 236 237 unsigned 238 sdis_medium_get_id(const struct sdis_medium* medium) 239 { 240 ASSERT(medium); 241 return medium->id.index; 242 } 243