progress.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* Copyright (C) 2001-2017 Peter Selinger.
  2. This file is part of Potrace. It is free software and it is covered
  3. by the GNU General Public License. See the file COPYING for details. */
  4. /* operations on potrace_progress_t objects, which are defined in
  5. potracelib.h. Note: the code attempts to minimize runtime overhead
  6. when no progress monitoring was requested. It also tries to
  7. minimize excessive progress calculations beneath the "epsilon"
  8. threshold. */
  9. #ifndef PROGRESS_H
  10. #define PROGRESS_H
  11. /* structure to hold progress bar callback data */
  12. struct progress_s {
  13. void (*callback)(double progress, void *privdata); /* callback fn */
  14. void *data; /* callback function's private data */
  15. double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */
  16. double epsilon; /* granularity: can skip smaller increments */
  17. double b; /* upper limit of subrange in superrange units */
  18. double d_prev; /* previous value of d */
  19. };
  20. typedef struct progress_s progress_t;
  21. /* notify given progress object of current progress. Note that d is
  22. given in the 0.0-1.0 range, which will be scaled and translated to
  23. the progress object's range. */
  24. static inline void progress_update(double d, progress_t *prog) {
  25. double d_scaled;
  26. if (prog != NULL && prog->callback != NULL) {
  27. d_scaled = prog->min * (1-d) + prog->max * d;
  28. if (d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon) {
  29. prog->callback(prog->min * (1-d) + prog->max * d, prog->data);
  30. prog->d_prev = d_scaled;
  31. }
  32. }
  33. }
  34. /* start a subrange of the given progress object. The range is
  35. narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range
  36. is below granularity threshold, disable further subdivisions. */
  37. static inline void progress_subrange_start(double a, double b, const progress_t *prog, progress_t *sub) {
  38. double min, max;
  39. if (prog == NULL || prog->callback == NULL) {
  40. sub->callback = NULL;
  41. return;
  42. }
  43. min = prog->min * (1-a) + prog->max * a;
  44. max = prog->min * (1-b) + prog->max * b;
  45. if (max - min < prog->epsilon) {
  46. sub->callback = NULL; /* no further progress info in subrange */
  47. sub->b = b;
  48. return;
  49. }
  50. sub->callback = prog->callback;
  51. sub->data = prog->data;
  52. sub->epsilon = prog->epsilon;
  53. sub->min = min;
  54. sub->max = max;
  55. sub->d_prev = prog->d_prev;
  56. return;
  57. }
  58. static inline void progress_subrange_end(progress_t *prog, progress_t *sub) {
  59. if (prog != NULL && prog->callback != NULL) {
  60. if (sub->callback == NULL) {
  61. progress_update(sub->b, prog);
  62. } else {
  63. prog->d_prev = sub->d_prev;
  64. }
  65. }
  66. }
  67. #endif /* PROGRESS_H */