value-expanders.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma once
  2. #include "flipper.h"
  3. #include "valuemutex.h"
  4. #include "pubsub.h"
  5. #include "event.h"
  6. #include "m-list.h"
  7. /*
  8. == Value composer ==
  9. */
  10. typedef struct ValueComposer ValueComposer;
  11. typedef void (*ValueComposerCallback)(void* ctx, void* state);
  12. typedef enum { UiLayerBelowNotify, UiLayerNotify, UiLayerAboveNotify } UiLayer;
  13. typedef struct {
  14. ValueComposerCallback cb;
  15. void* ctx;
  16. UiLayer layer;
  17. ValueComposer* composer;
  18. } ValueComposerHandle;
  19. LIST_DEF(list_composer_cb, ValueComposerHandle, M_POD_OPLIST);
  20. struct ValueComposer {
  21. ValueMutex value;
  22. list_composer_cb_t layers[3];
  23. osMutexId_t mutex;
  24. Event request;
  25. };
  26. void COPY_COMPOSE(void* ctx, void* state);
  27. bool init_composer(ValueComposer* composer, void* value);
  28. /*
  29. Free resources allocated by `init_composer`.
  30. This function doesn't free the memory occupied by `ValueComposer` itself.
  31. */
  32. bool delete_composer(ValueComposer* composer);
  33. ValueComposerHandle*
  34. add_compose_layer(ValueComposer* composer, ValueComposerCallback cb, void* ctx, UiLayer layer);
  35. bool remove_compose_layer(ValueComposerHandle* handle);
  36. void request_compose(ValueComposerHandle* handle);
  37. /*
  38. Perform composition if requested.
  39. `start_cb` and `end_cb` will be called before and after all layer callbacks, respectively.
  40. Both `start_cb` and `end_cb` can be NULL. They can be used to set initial state (e.g. clear screen)
  41. and commit the final state.
  42. */
  43. void perform_compose(
  44. ValueComposer* composer,
  45. ValueComposerCallback start_cb,
  46. ValueComposerCallback end_cb,
  47. void* ctx);
  48. /*
  49. Perform composition.
  50. This function should be called with value mutex acquired.
  51. This function is here for convenience, so that developers can write their own compose loops.
  52. See `perform_compose` function body for an example.
  53. */
  54. void perform_compose_internal(ValueComposer* composer, void* state);
  55. // See [LED](LED-API) or [Display](Display-API) API for examples.
  56. /*
  57. == ValueManager ==
  58. More complicated concept is ValueManager.
  59. It is like ValueMutex, but user can subscribe to value updates.
  60. First of all you can use value and pubsub part as showing above:
  61. aquire/release mutex, read value, subscribe/unsubscribe pubsub.
  62. There are two specific methods for ValueManager: write_managed, commit_managed
  63. */
  64. typedef struct {
  65. ValueMutex value;
  66. PubSub pubsub;
  67. } ValueManager;
  68. bool init_managed(ValueManager* managed, void* value, size_t size);
  69. /*
  70. Free resources allocated by `init_managed`.
  71. This function doesn't free the memory occupied by `ValueManager` itself.
  72. */
  73. bool delete_managed(ValueManager* managed);
  74. /*
  75. acquire value, changes it and send notify with current value.
  76. */
  77. bool write_managed(ValueManager* managed, void* data, size_t len, uint32_t timeout);
  78. /*
  79. commit_managed works as `release_mutex` but send notify with current value.
  80. */
  81. bool commit_managed(ValueManager* managed, void* value);