ev.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * Copyright (c) 2019, sogwyms@gmail.com
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * @version 0.1.0
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2019-12-01 sogwms The first version
  11. * 2019-01-16 sogwms Add orderly startup support
  12. */
  13. #include "ev.h"
  14. #define DBG_SECTION_NAME "ev"
  15. #define DBG_LEVEL DBG_LOG
  16. #include <rtdbg.h>
  17. const int g_levels_table[] = EV_OBJ_LEVELS;
  18. static ev_t global_ev = RT_NULL;
  19. int ev_object_install(ev_object_t obj, int type)
  20. {
  21. RT_ASSERT(global_ev != RT_NULL);
  22. obj->type = (enum ev_obj_type)type;
  23. pss_init_client(&obj->pssc);
  24. rt_list_insert_after(&global_ev->components_head, &obj->list);
  25. return RT_EOK;
  26. }
  27. enum {
  28. _OBJ_METHOD_START,
  29. _OBJ_METHOD_STOP,
  30. };
  31. static int __traverse_object_method(ev_t ev, int method)
  32. {
  33. rt_list_t *node;
  34. struct ev_object *obj;
  35. for (int ix = 0; ix < sizeof(g_levels_table)/sizeof(g_levels_table[0]); ix++)
  36. {
  37. rt_list_for_each(node, &ev->components_head)
  38. {
  39. obj = rt_list_entry(node, struct ev_object, list);
  40. if (g_levels_table[ix] != obj->type)
  41. continue;
  42. if (method == _OBJ_METHOD_START)
  43. {
  44. if (obj->flag & EV_FLAG_ACTIVATED)
  45. return RT_ERROR;
  46. obj->flag |= EV_FLAG_ACTIVATED;
  47. if (obj->start(obj) != RT_EOK)
  48. return RT_ERROR;
  49. }
  50. else if (method == _OBJ_METHOD_STOP)
  51. {
  52. if (!(obj->flag & EV_FLAG_ACTIVATED))
  53. return RT_ERROR;
  54. obj->flag &= (~EV_FLAG_ACTIVATED);
  55. if (obj->stop(obj) != RT_EOK)
  56. return RT_ERROR;
  57. }
  58. }
  59. }
  60. return RT_EOK;
  61. }
  62. int ev_startup(ev_t ev)
  63. {
  64. int rvl;
  65. LOG_D("Starting...");
  66. rvl = __traverse_object_method(ev, _OBJ_METHOD_START);
  67. if (rvl == RT_EOK)
  68. LOG_D("OK!");
  69. else
  70. LOG_D("FAILED!");
  71. return rvl;
  72. }
  73. int ev_stop(ev_t ev)
  74. {
  75. int rvl;
  76. LOG_D("Stopping...");
  77. rvl = __traverse_object_method(ev, _OBJ_METHOD_STOP);
  78. if (rvl == RT_EOK)
  79. LOG_D("OK!");
  80. else
  81. LOG_D("FAILED!");
  82. return rvl;
  83. }
  84. int ev_init(ev_t ev)
  85. {
  86. RT_ASSERT(ev != RT_NULL);
  87. global_ev = ev;
  88. rt_list_init(&ev->components_head);
  89. ev->startup = ev_startup;
  90. ev->stop = ev_stop;
  91. return RT_EOK;
  92. }