Skip to content

Commit 9d15df9

Browse files
authored
Merge pull request #99 from saxbophone/develop
version 0.18.0
2 parents 17e8b4c + 80eb953 commit 9d15df9

File tree

4 files changed

+86
-20
lines changed

4 files changed

+86
-20
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# begin basic metadata
22
cmake_minimum_required(VERSION 3.0)
33

4-
project(libsaxbospiral VERSION 0.17.1 LANGUAGES C)
4+
project(libsaxbospiral VERSION 0.18.0 LANGUAGES C)
55
set(CMAKE_C_STANDARD 99)
66
set(CMAKE_C_STANDARD_REQUIRED ON)
77
set(

saxbospiral/solve.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,23 +240,28 @@ sxbp_status_t sxbp_resize_spiral(
240240
* given a pointer to a spiral spiral for which the length of all its lines are
241241
* not yet known, a perfection threshold (-1 for no perfection, or otherwise
242242
* the maximmum line length at which to allow aggressive optimisation), the
243-
* index of the highest line to plot to and a pointer to a callback function,
243+
* index of the highest line to plot to, a pointer to a callback function and
244+
* a void pointer to a user-defined data struct for use with the callback,
244245
* calculate the length needed for each line in the spiral up to this index
245246
* (to avoid line overlap) and store these in a the spiral struct that is
246247
* pointed to by the pointer. If the spiral has some lines already solved, the
247248
* algorithm will start at the next unsolved line.
248-
* the function pointer can be NULL, if it is not then it will be called every
249-
* time a new line of the spiral is solved. The function should be of return
250-
* type void and take three arguments: a pointer to a spiral_t struct, an
251-
* integer specifying the index of the latest solved line and an integer
252-
* specifying the index of the highest line that will be solved.
249+
* the function pointer and the user data pointer can be NULL.
250+
* If the function pointer is not NULL, then it will be called every time a new
251+
* line of the spiral is solved. The function should be of return type void and
252+
* take four arguments: a pointer to a spiral_t struct, an integer specifying
253+
* the index of the latest solved line, an integer specifying the index of the
254+
* highest line that will be solved and a void pointer used for accessing the
255+
* user data.
253256
* returns a status struct (used for error information)
254257
*/
255258
sxbp_status_t sxbp_plot_spiral(
256259
sxbp_spiral_t* spiral, int perfection_threshold, uint64_t max_line,
257260
void(* progress_callback)(
258-
sxbp_spiral_t* spiral, uint64_t latest_line, uint64_t target_line
259-
)
261+
sxbp_spiral_t* spiral, uint64_t latest_line, uint64_t target_line,
262+
void* progress_callback_user_data
263+
),
264+
void* progress_callback_user_data
260265
) {
261266
// set up result status
262267
sxbp_status_t result = {{0, 0, 0}, 0};
@@ -271,7 +276,7 @@ sxbp_status_t sxbp_plot_spiral(
271276
}
272277
// call callback if given
273278
if(progress_callback != NULL) {
274-
progress_callback(spiral, i, max_index);
279+
progress_callback(spiral, i, max_index, progress_callback_user_data);
275280
}
276281
}
277282
// all ok

saxbospiral/solve.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,28 @@ sxbp_status_t sxbp_resize_spiral(
2727
* given a pointer to a spiral spiral for which the length of all its lines are
2828
* not yet known, a perfection threshold (-1 for no perfection, or otherwise
2929
* the maximmum line length at which to allow aggressive optimisation), the
30-
* index of the highest line to plot to and a pointer to a callback function,
30+
* index of the highest line to plot to, a pointer to a callback function and
31+
* a void pointer to a user-defined data struct for use with the callback,
3132
* calculate the length needed for each line in the spiral up to this index
3233
* (to avoid line overlap) and store these in a the spiral struct that is
3334
* pointed to by the pointer. If the spiral has some lines already solved, the
3435
* algorithm will start at the next unsolved line.
35-
* the function pointer can be NULL, if it is not then it will be called every
36-
* time a new line of the spiral is solved. The function should be of return
37-
* type void and take three arguments: a pointer to a spiral_t struct, an
38-
* integer specifying the index of the latest solved line and an integer
39-
* specifying the index of the highest line that will be solved.
36+
* the function pointer and the user data pointer can be NULL.
37+
* If the function pointer is not NULL, then it will be called every time a new
38+
* line of the spiral is solved. The function should be of return type void and
39+
* take four arguments: a pointer to a spiral_t struct, an integer specifying
40+
* the index of the latest solved line, an integer specifying the index of the
41+
* highest line that will be solved and a void pointer used for accessing the
42+
* user data.
4043
* returns a status struct (used for error information)
4144
*/
4245
sxbp_status_t sxbp_plot_spiral(
4346
sxbp_spiral_t* spiral, int perfection_threshold, uint64_t max_line,
4447
void(* progress_callback)(
45-
sxbp_spiral_t* spiral, uint64_t latest_line, uint64_t target_line
46-
)
48+
sxbp_spiral_t* spiral, uint64_t latest_line, uint64_t target_line,
49+
void* progress_callback_user_data
50+
),
51+
void* progress_callback_user_data
4752
);
4853

4954
#ifdef __cplusplus

tests.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ bool test_sxbp_plot_spiral() {
205205
}
206206

207207
// call plot_spiral on spiral
208-
sxbp_plot_spiral(&spiral, 1, 16, NULL);
208+
sxbp_plot_spiral(&spiral, 1, 16, NULL, NULL);
209209

210210
// check solved count
211211
if(spiral.solved_count != expected.solved_count) {
@@ -249,7 +249,7 @@ bool test_sxbp_plot_spiral_partial() {
249249
}
250250

251251
// call plot_spiral on spiral, with instruction to only plot up to line 9
252-
sxbp_plot_spiral(&spiral, 1, 9, NULL);
252+
sxbp_plot_spiral(&spiral, 1, 9, NULL, NULL);
253253

254254
// check solved count
255255
if(spiral.solved_count != expected.solved_count) {
@@ -270,6 +270,58 @@ bool test_sxbp_plot_spiral_partial() {
270270
return result;
271271
}
272272

273+
/*
274+
* disable GCC warning about the unused parameters as this function by necessity
275+
* requires these arguments in its signature, but it needn't use all of them.
276+
*/
277+
#pragma GCC diagnostic push
278+
#pragma GCC diagnostic ignored "-Wunused-parameter"
279+
// test callback for next test case
280+
static void test_progress_callback(
281+
sxbp_spiral_t* spiral, uint64_t latest_line, uint64_t target_line,
282+
void* progress_callback_user_data
283+
) {
284+
// cast user data from void pointer to uint16_t pointer, deref and multiply
285+
*(uint16_t*)progress_callback_user_data *= 13;
286+
}
287+
// re-enable all warnings
288+
#pragma GCC diagnostic pop
289+
290+
bool test_sxbp_plot_spiral_progress_callback() {
291+
// success / failure variable
292+
bool result = true;
293+
// build input structs
294+
sxbp_spiral_t spiral = { .size = 16, };
295+
spiral.lines = calloc(sizeof(sxbp_line_t), 16);
296+
sxbp_direction_t directions[16] = {
297+
SXBP_UP, SXBP_LEFT, SXBP_DOWN, SXBP_LEFT, SXBP_DOWN, SXBP_RIGHT,
298+
SXBP_DOWN, SXBP_RIGHT, SXBP_UP, SXBP_LEFT, SXBP_UP, SXBP_RIGHT,
299+
SXBP_DOWN, SXBP_RIGHT, SXBP_UP, SXBP_LEFT,
300+
};
301+
for(uint8_t i = 0; i < 16; i++) {
302+
spiral.lines[i].direction = directions[i];
303+
spiral.lines[i].length = 0;
304+
}
305+
// create user data variable
306+
uint16_t user_data = 17;
307+
308+
/*
309+
* call plot_spiral on spiral, with instruction to only plot up to line 1
310+
* supply our progress_callback function and a user data variable
311+
*/
312+
sxbp_plot_spiral(&spiral, 1, 1, test_progress_callback, (void*)&user_data);
313+
314+
// user data variable should have been set to 221 (17 * 13) by callback
315+
if(user_data != 221) {
316+
result = false;
317+
}
318+
319+
// free memory
320+
free(spiral.lines);
321+
322+
return result;
323+
}
324+
273325
bool test_sxbp_load_spiral() {
274326
// success / failure variable
275327
bool result = true;
@@ -599,6 +651,10 @@ int main() {
599651
result = run_test_case(
600652
result, test_sxbp_plot_spiral_partial, "test_sxbp_plot_spiral_partial"
601653
);
654+
result = run_test_case(
655+
result, test_sxbp_plot_spiral_progress_callback,
656+
"test_sxbp_plot_spiral_progress_callback"
657+
);
602658
result = run_test_case(
603659
result, test_sxbp_load_spiral, "test_sxbp_load_spiral"
604660
);

0 commit comments

Comments
 (0)