commit 5e32fe8a48d0f6722e1984b051ba172872a2f650
parent ce6e48ba25e3bf09b5835a1393a036e3e999d22c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 15 Dec 2017 15:12:59 +0100
Implement the interface API
Diffstat:
2 files changed, 144 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -44,6 +44,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SDIS_FILES_SRC
sdis_data.c
sdis_device.c
+ sdis_interface.c
sdis_medium.c)
set(SDIS_FILES_INC_API
diff --git a/src/sdis_interface.c b/src/sdis_interface.c
@@ -0,0 +1,143 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "sdis.h"
+#include "sdis_device_c.h"
+
+#include <rsys/mem_allocator.h>
+
+struct sdis_interface {
+ struct sdis_medium* medium_front;
+ struct sdis_medium* medium_back;
+ struct sdis_interface_shader shader;
+ struct sdis_data* data;
+
+ ref_T ref;
+ struct sdis_device* dev;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static int
+check_interface_shader
+ (const struct sdis_interface_shader* shader,
+ const struct sdis_medium* front,
+ const struct sdis_medium* back)
+{
+ ASSERT(shader && front && back);
+
+ if(sdis_medium_get_type(front) != sdis_medium_get_type(back)
+ && shader->convection_coef == NULL) { /* Fluid<->solid interface */
+ return 0;
+ }
+ return 1;
+}
+
+static void
+interface_release(ref_T* ref)
+{
+ struct sdis_interface* interface = NULL;
+ struct sdis_device* dev = NULL;
+ ASSERT(ref);
+ interface = CONTAINER_OF(ref, struct sdis_interface, ref);
+ dev = interface->dev;
+ if(interface->medium_front) SDIS(medium_ref_put(interface->medium_front));
+ if(interface->medium_back) SDIS(medium_ref_put(interface->medium_back));
+ if(interface->data) SDIS(data_ref_put(interface->data));
+ MEM_RM(dev->allocator, interface);
+ SDIS(device_ref_put(dev));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sdis_interface_create
+ (struct sdis_device* dev,
+ struct sdis_medium* front,
+ struct sdis_medium* back,
+ const struct sdis_interface_shader* shader,
+ struct sdis_data* data,
+ struct sdis_interface** out_interface)
+{
+ struct sdis_interface* interface = NULL;
+ res_T res = RES_OK;
+
+ if(!dev || !front || !back || !shader || !out_interface) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(sdis_medium_get_type(front) == SDIS_MEDIUM_FLUID
+ && sdis_medium_get_type(back) == SDIS_MEDIUM_FLUID) {
+ log_err(dev, "%s: invalid fluid<->fluid interface.\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(!check_interface_shader(shader, front, back)) {
+ log_err(dev, "%s: invalid interface shader.\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ interface = MEM_CALLOC(dev->allocator, 1, sizeof(struct sdis_interface));
+ if(!interface) {
+ log_err(dev, "%s: could not create the interface.\n", FUNC_NAME);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&interface->ref);
+ SDIS(medium_ref_get(front));
+ SDIS(medium_ref_get(back));
+ SDIS(device_ref_get(dev));
+ interface->medium_front = front;
+ interface->medium_back = back;
+ interface->dev = dev;
+ interface->shader = *shader;
+
+ if(data) {
+ SDIS(data_ref_get(data));
+ interface->data = data;
+ }
+
+exit:
+ if(out_interface) *out_interface = interface;
+ return res;
+error:
+ if(interface) {
+ SDIS(interface_ref_put(interface));
+ interface = NULL;
+ }
+ goto exit;
+}
+
+res_T
+sdis_interface_ref_get(struct sdis_interface* interface)
+{
+ if(!interface) return RES_BAD_ARG;
+ ref_get(&interface->ref);
+ return RES_OK;
+}
+
+res_T
+sdis_interface_ref_put(struct sdis_interface* interface)
+{
+ if(!interface) return RES_BAD_ARG;
+ ref_put(&interface->ref, interface_release);
+ return RES_OK;
+}
+