Easier and simpler task control

This commit is contained in:
Hugues Delorme 2013-03-05 01:04:29 +01:00
parent 85b616e84b
commit d128eb92fd
12 changed files with 89 additions and 156 deletions

View File

@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 2.6)
include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckCSourceCompiles)
project(foug_datax C)
@ -17,19 +15,6 @@ check_include_files(stdint.h HAVE_STDINT_H)
configure_file(src/c/config.h.cmake config.h @ONLY)
include_directories(${CMAKE_BINARY_DIR}) # For generated "config.h"
# Have fabsf() ?
#check_symbol_exists(fabs "math.h" HAVE_FABS)
#check_symbol_exists(fabsf "math.h" HAVE_FABSF)
#check_c_source_compiles("
# #include <math.h>
# int main()
# {
# fabsf(-1);
# return 0;
# }"
# HAVE_FABSF)
# Specific flags for gcc
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi -pedantic-errors -fstrict-aliasing")

View File

@ -31,7 +31,8 @@ HEADERS += \
../../../src/c/libstl/stlb_read.h \
../../../src/c/libstl/stlb_write.h \
../../../src/c/libstl/stl_triangle.h \
../../../src/c/libstl/stlb_triangle.h
../../../src/c/libstl/stlb_triangle.h \
../../../src/c/error.h
SOURCES += \
../../../src/c/endian.c \
@ -39,7 +40,8 @@ SOURCES += \
../../../src/c/task_control.c \
../../../src/c/libstl/stla_read.c \
../../../src/c/libstl/stlb_read.c \
../../../src/c/libstl/stlb_write.c
../../../src/c/libstl/stlb_write.c \
../../../src/c/error.c
*-g++*:QMAKE_CFLAGS += -ansi -pedantic-errors
*-msvc*:QMAKE_CFLAGS += -TC

11
src/c/error.c Normal file
View File

@ -0,0 +1,11 @@
#include "error.h"
foug_bool_t foug_datax_no_error(int code)
{
return code == FOUG_DATAX_NO_ERROR;
}
foug_bool_t foug_datax_error(int code)
{
return code != FOUG_DATAX_NO_ERROR;
}

16
src/c/error.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef FOUG_C_DATAX_ERROR_H
#define FOUG_C_DATAX_ERROR_H
#include "global.h"
/* Common errors */
#define FOUG_DATAX_NO_ERROR 0
#define FOUG_DATAX_NULL_BUFFER_ERROR -1
#define FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR -2
#define FOUG_DATAX_STREAM_ERROR -3
#define FOUG_DATAX_TASK_STOPPED_ERROR -4
FOUG_LIB_EXPORT foug_bool_t foug_datax_no_error(int code);
FOUG_LIB_EXPORT foug_bool_t foug_datax_error(int code);
#endif /* FOUG_C_DATAX_ERROR_H */

View File

@ -1,5 +1,7 @@
#include "stla_read.h"
#include "../error.h"
#include <ctype.h> /* isspace() */
#include <errno.h>
#include <stdlib.h>
@ -15,7 +17,6 @@ typedef struct foug_stream_fwd_iterator
void* cookie;
void (*stream_read_hook)(const struct foug_stream_fwd_iterator* it);
} foug_stream_fwd_iterator_t;
static void foug_stream_fwd_iterator_read_hook(const foug_stream_fwd_iterator_t* it)
@ -221,7 +222,6 @@ static int eat_facet(foug_stream_fwd_iterator_t* it,
int foug_stla_read(foug_stla_read_args_t *args)
{
foug_task_progress_t progress;
char fixed_buffer[FOUG_STLA_READ_STRING_BUFFER_LEN];
foug_string_buffer_t string_buffer;
foug_stl_triangle_t triangle;
@ -229,9 +229,9 @@ int foug_stla_read(foug_stla_read_args_t *args)
int eat_facet_result;
if (args->buffer == NULL)
return FOUG_STLA_READ_NULL_BUFFER;
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (args->buffer_size == 0)
return FOUG_STLA_READ_INVALID_BUFFER_SIZE_ERROR;
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
it.stream = &(args->stream);
it.buffer = args->buffer;
@ -246,11 +246,6 @@ int foug_stla_read(foug_stla_read_args_t *args)
string_buffer.max_len = FOUG_STLA_READ_STRING_BUFFER_LEN;
string_buffer.len = 0;
progress.range_min = 0.f;
progress.range_max = (foug_real32_t)args->data_size_hint;
progress.value = 0.f;
args->task_control.is_stop_requested = 0;
/* Eat solids */
while (eat_token(&it, "solid") == 0) {
/* Try to eat solid's name */
@ -283,5 +278,5 @@ int foug_stla_read(foug_stla_read_args_t *args)
}
}
return FOUG_STLA_READ_NO_ERROR;
return FOUG_DATAX_NO_ERROR;
}

View File

@ -3,6 +3,7 @@
#include "stl_global.h"
#include "stl_triangle.h"
#include "../error.h"
#include "../stream.h"
#include "../task_control.h"
@ -31,18 +32,7 @@ typedef struct foug_stla_read_args
FOUG_DATAX_LIBSTL_EXPORT
int foug_stla_read(foug_stla_read_args_t* args);
#define FOUG_DATAX_NO_ERROR 0
#define FOUG_DATAX_NULL_BUFFER -1
#define FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR -2
#define FOUG_DATAX_STREAM_ERROR -3
#define FOUG_DATAX_TASK_STOPPED_ERROR -4
/* Error codes returned by foug_stlb_read() */
#define FOUG_STLA_READ_NO_ERROR 0
#define FOUG_STLA_READ_NULL_BUFFER 3
#define FOUG_STLA_READ_INVALID_BUFFER_SIZE_ERROR 4
#define FOUG_STLA_READ_PARSE_ERROR 5
#define FOUG_STLA_READ_STREAM_ERROR 7
#define FOUG_STLA_READ_TASK_STOPPED_ERROR 8
/* Error codes returned by foug_stla_read() */
#define FOUG_STLA_READ_PARSE_ERROR 1
#endif /* FOUG_C_LIBSTL_STLA_READ_H */

View File

@ -1,12 +1,8 @@
#include "stlb_read.h"
#include "../error.h"
#include "../endian.h"
static foug_bool_t foug_stlb_no_error(int code)
{
return code == FOUG_STLB_READ_NO_ERROR;
}
static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom_input,
uint8_t* buffer,
uint32_t facet_count)
@ -31,7 +27,7 @@ static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom_input,
int foug_stlb_read(foug_stlb_read_args_t *args)
{
foug_task_progress_t progress;
uint8_t progress_pc;
uint8_t header_data[FOUG_STLB_HEADER_SIZE];
uint32_t total_facet_count;
size_t buffer_facet_count;
@ -40,9 +36,9 @@ int foug_stlb_read(foug_stlb_read_args_t *args)
size_t facet_count_read;
if (args->buffer == NULL)
return FOUG_STLB_READ_NULL_BUFFER;
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (args->buffer_size < FOUG_STLB_MIN_CONTENTS_SIZE)
return FOUG_STLB_READ_INVALID_BUFFER_SIZE_ERROR;
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
/* Read header */
if (foug_stream_read(&args->stream, header_data, 1, FOUG_STLB_HEADER_SIZE) != FOUG_STLB_HEADER_SIZE)
@ -59,42 +55,33 @@ int foug_stlb_read(foug_stlb_read_args_t *args)
if (args->geom_input.begin_triangles_func != NULL)
args->geom_input.begin_triangles_func(&args->geom_input, total_facet_count);
progress.range_min = 0.f;
progress.range_max = (foug_real32_t)total_facet_count;
progress.value = 0.f;
args->task_control.is_stop_requested = 0;
/* Read triangles */
buffer_facet_count = args->buffer_size / FOUG_STLB_TRIANGLE_SIZE;
accum_facet_count_read = 0;
error = FOUG_STLB_READ_NO_ERROR;
while (foug_stlb_no_error(error) && accum_facet_count_read < total_facet_count) {
error = FOUG_DATAX_NO_ERROR;
while (foug_datax_no_error(error) && accum_facet_count_read < total_facet_count) {
facet_count_read = foug_stream_read(&args->stream,
args->buffer, FOUG_STLB_TRIANGLE_SIZE, buffer_facet_count);
if (foug_stream_error(&args->stream) != 0)
error = FOUG_STLB_READ_STREAM_ERROR;
error = FOUG_DATAX_STREAM_ERROR;
else if (facet_count_read > 0)
error = FOUG_STLB_READ_NO_ERROR;
error = FOUG_DATAX_NO_ERROR;
else
break; /* Exit if no facet to read */
if (foug_stlb_no_error(error)) {
if (foug_datax_no_error(error)) {
foug_stlb_read_facets(&args->geom_input, args->buffer, facet_count_read);
accum_facet_count_read += facet_count_read;
if (args->task_control.is_stop_requested) {
error = FOUG_STLB_READ_TASK_STOPPED_ERROR;
foug_task_control_handle_stop(&args->task_control);
}
else {
foug_task_control_set_progress(&args->task_control, &progress, accum_facet_count_read);
}
progress_pc = foug_percentage(0, total_facet_count, accum_facet_count_read);
if (!foug_task_control_handle_progress(&args->task_control, progress_pc))
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
} /* end while */
if (foug_stlb_no_error(error) && args->geom_input.end_triangles_func != NULL)
if (foug_datax_no_error(error) && args->geom_input.end_triangles_func != NULL)
args->geom_input.end_triangles_func(&args->geom_input);
if (foug_stlb_no_error(error) && accum_facet_count_read != total_facet_count)
if (foug_datax_no_error(error) && accum_facet_count_read != total_facet_count)
error = FOUG_STLB_READ_FACET_COUNT_ERROR;
return error;
}

View File

@ -3,6 +3,7 @@
#include "stl_global.h"
#include "stlb_triangle.h"
#include "../error.h"
#include "../stream.h"
#include "../task_control.h"
@ -31,12 +32,7 @@ FOUG_DATAX_LIBSTL_EXPORT
int foug_stlb_read(foug_stlb_read_args_t* args);
/* Error codes returned by foug_stlb_read() */
#define FOUG_STLB_READ_NO_ERROR 0
#define FOUG_STLB_READ_NULL_BUFFER 3
#define FOUG_STLB_READ_INVALID_BUFFER_SIZE_ERROR 4
#define FOUG_STLB_READ_HEADER_WRONG_SIZE_ERROR 5
#define FOUG_STLB_READ_FACET_COUNT_ERROR 6
#define FOUG_STLB_READ_STREAM_ERROR 7
#define FOUG_STLB_READ_TASK_STOPPED_ERROR 8
#define FOUG_STLB_READ_HEADER_WRONG_SIZE_ERROR 1
#define FOUG_STLB_READ_FACET_COUNT_ERROR 2
#endif /* FOUG_C_LIBSTL_STLB_READ_H */

View File

@ -1,14 +1,9 @@
#include "stlb_write.h"
#include "stlb_triangle.h"
#include "../endian.h"
#include "../error.h"
#include <string.h>
static foug_bool_t foug_stlb_no_error(int code)
{
return code == FOUG_STLB_WRITE_NO_ERROR;
}
static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom_output,
uint8_t* buffer,
uint32_t ifacet_start,
@ -32,7 +27,6 @@ static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom_output,
int foug_stlb_write(foug_stlb_write_args_t *args)
{
foug_task_progress_t progress;
uint8_t header_data[FOUG_STLB_HEADER_SIZE];
uint32_t facet_count;
uint32_t i_facet;
@ -41,9 +35,9 @@ int foug_stlb_write(foug_stlb_write_args_t *args)
int error;
if (args->buffer == NULL)
return FOUG_STLB_WRITE_NULL_BUFFER_ERROR;
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (args->buffer_size < FOUG_STLB_MIN_CONTENTS_SIZE)
return FOUG_STLB_WRITE_INVALID_BUFFER_SIZE_ERROR;
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
if (args->geom_output.get_triangle_count_func == NULL)
return FOUG_STLB_WRITE_NULL_GET_TRIANGLE_COUNT_FUNC;
if (args->geom_output.get_triangle_func == NULL)
@ -56,26 +50,21 @@ int foug_stlb_write(foug_stlb_write_args_t *args)
memset(header_data, 0, FOUG_STLB_HEADER_SIZE);
if (foug_stream_write(&args->stream, header_data, FOUG_STLB_HEADER_SIZE, 1) != 1)
return FOUG_STLB_WRITE_STREAM_ERROR;
return FOUG_DATAX_STREAM_ERROR;
/* Write facet count */
facet_count = args->geom_output.get_triangle_count_func(&args->geom_output);
foug_encode_uint32_le(facet_count, args->buffer);
if (foug_stream_write(&args->stream, args->buffer, sizeof(uint32_t), 1) != 1)
return FOUG_STLB_WRITE_STREAM_ERROR;
progress.range_min = 0.f;
progress.range_max = (foug_real32_t)facet_count;
progress.value = 0.f;
args->task_control.is_stop_requested = 0;
return FOUG_DATAX_STREAM_ERROR;
/* Write triangles */
error = FOUG_STLB_WRITE_NO_ERROR;
error = FOUG_DATAX_NO_ERROR;
buffer_facet_count = args->buffer_size / FOUG_STLB_TRIANGLE_SIZE;
ifacet_start = 0;
for (i_facet = 0;
i_facet < facet_count && foug_stlb_no_error(error);
i_facet < facet_count && foug_datax_no_error(error);
i_facet += buffer_facet_count)
{
/* Write to buffer */
@ -88,17 +77,15 @@ int foug_stlb_write(foug_stlb_write_args_t *args)
if (foug_stream_write(&args->stream, args->buffer, FOUG_STLB_TRIANGLE_SIZE, buffer_facet_count)
!= buffer_facet_count)
{
error = FOUG_STLB_WRITE_STREAM_ERROR;
error = FOUG_DATAX_STREAM_ERROR;
}
/* Task control */
if (foug_stlb_no_error(error)) {
if (args->task_control.is_stop_requested) {
foug_task_control_handle_stop(&args->task_control);
error = FOUG_STLB_WRITE_TASK_STOPPED_ERROR;
}
else {
foug_task_control_set_progress(&args->task_control, &progress, i_facet + 1);
if (foug_datax_no_error(error)) {
if (!foug_task_control_handle_progress(&args->task_control,
foug_percentage(0, facet_count, i_facet + 1)))
{
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
}
} /* end for */

View File

@ -3,6 +3,7 @@
#include "stl_global.h"
#include "stlb_triangle.h"
#include "../error.h"
#include "../stream.h"
#include "../task_control.h"
@ -30,12 +31,7 @@ FOUG_DATAX_LIBSTL_EXPORT
int foug_stlb_write(foug_stlb_write_args_t* args);
/* Error codes returned by foug_stlb_write() */
#define FOUG_STLB_WRITE_NO_ERROR 0
#define FOUG_STLB_WRITE_NULL_BUFFER_ERROR 3
#define FOUG_STLB_WRITE_NULL_GET_TRIANGLE_COUNT_FUNC 4
#define FOUG_STLB_WRITE_NULL_GET_TRIANGLE_FUNC 5
#define FOUG_STLB_WRITE_STREAM_ERROR 6
#define FOUG_STLB_WRITE_TASK_STOPPED_ERROR 7
#define FOUG_STLB_WRITE_INVALID_BUFFER_SIZE_ERROR 8
#define FOUG_STLB_WRITE_NULL_GET_TRIANGLE_COUNT_FUNC 1
#define FOUG_STLB_WRITE_NULL_GET_TRIANGLE_FUNC 2
#endif /* FOUG_C_LIBSTL_STLB_WRITE_H */

View File

@ -3,37 +3,20 @@
#include <math.h>
#include <string.h>
/* foug_task_control */
foug_real32_t foug_task_progress_get_value_pc(const foug_task_progress_t *progress)
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc)
{
if (progress == NULL)
return 0.f;
return fabs((progress->value - progress->range_min) / (progress->range_max - progress->range_min));
if (ctrl != NULL && ctrl->handle_progress_func != NULL)
return ctrl->handle_progress_func(ctrl, progress_pc);
return 1;
}
FOUG_LIB_EXPORT void foug_task_control_set_progress(foug_task_control_t* ctrl,
foug_task_progress_t *progress,
foug_real32_t value)
uint8_t foug_percentage(size_t range_min, size_t range_max, size_t value)
{
progress->value = value;
if (ctrl->handle_progress_update_func != NULL)
ctrl->handle_progress_update_func(ctrl, progress);
}
/* Task stop */
void foug_task_control_async_stop(foug_task_control_t* ctrl)
{
if (ctrl != NULL)
ctrl->is_stop_requested = 1;
}
void foug_task_control_handle_stop(foug_task_control_t* ctrl)
{
if (ctrl != NULL) {
ctrl->is_stop_requested = 0;
if (ctrl->handle_stop_func != NULL)
ctrl->handle_stop_func(ctrl);
}
if (value >= range_max)
return 100;
else if (value <= range_min)
return 0;
else if (range_min < range_max)
return (value * 100) / (range_max - range_min);
return 0;
}

View File

@ -4,33 +4,18 @@
#include "global.h"
#include "memory.h"
/* foug_task_progress */
typedef struct foug_task_progress
{
foug_real32_t range_min;
foug_real32_t range_max;
foug_real32_t value;
} foug_task_progress_t;
/* Progress */
FOUG_LIB_EXPORT foug_real32_t foug_task_progress_get_value_pc(const foug_task_progress_t* progress);
/* foug_task_control */
typedef struct foug_task_control foug_task_control_t;
struct foug_task_control
{
foug_bool_t is_stop_requested;
void* cookie;
void (*handle_stop_func)(foug_task_control_t*);
void (*handle_progress_update_func)(foug_task_control_t*, const foug_task_progress_t*);
foug_bool_t (*handle_progress_func)(foug_task_control_t*, uint8_t);
};
FOUG_LIB_EXPORT void foug_task_control_set_progress(foug_task_control_t* ctrl,
foug_task_progress_t* progress,
foug_real32_t value);
FOUG_LIB_EXPORT
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc);
/* Task stop */
FOUG_LIB_EXPORT void foug_task_control_async_stop(foug_task_control_t* ctrl);
FOUG_LIB_EXPORT void foug_task_control_handle_stop(foug_task_control_t* ctrl);
FOUG_LIB_EXPORT
uint8_t foug_percentage(size_t range_min, size_t range_max, size_t value);
#endif /* FOUG_C_TASK_CONTROL_H */