timer.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "timer.h"
  2. #include "util/time.h"
  3. #include "util/system.h"
  4. #include "util/file.h"
  5. #include "core/config.h"
  6. #include "core/statemanager.h"
  7. module::timer::~timer()
  8. {
  9. ::ithread::stop();
  10. ::ithread::wait();
  11. }
  12. std::string module::timer::add(const std::string& name, const std::string& filepath, const std::string& funname, int msec, bool loop)
  13. {
  14. std::string filepath2;
  15. if (ylib::file::exist(sConfig->website.dir + "/" + filepath))
  16. filepath2 = sConfig->website.dir + "/" + filepath;
  17. else
  18. {
  19. filepath2 = module_manager::getInstance()->search(filepath);
  20. if (filepath2.empty())
  21. {
  22. std::string result;
  23. result = "not found script lua, Root: " + std::string(sConfig->website.dir + "/" + filepath) + "\r\n Lib: ";
  24. for (size_t i = 0; i < sConfig->scripts.lib_dir.size(); i++)
  25. result.append(std::string(sConfig->scripts.lib_dir[i] + "/" + filepath)+"\r\n");
  26. return result;
  27. }
  28. }
  29. std::unique_lock<std::mutex> uni(module::timer::getInstance()->m_mutex);
  30. auto iter = module::timer::getInstance()->m_list.find(name);
  31. if (iter != module::timer::getInstance()->m_list.end())
  32. return "exist name `" + name + "`";
  33. timer_info ti;
  34. ti.name = name;
  35. ti.funname = funname;
  36. ti.filepath = filepath2;
  37. ti.loop = loop;
  38. ti.msec = msec;
  39. ti.exec_msec = time::now_msec() + msec;
  40. module::timer::getInstance()->m_list.emplace(name, ti);
  41. module::timer::getInstance()->m_insert = true;
  42. return "";
  43. }
  44. void module::timer::remove(const std::string& name)
  45. {
  46. module::timer::getInstance()->m_removed.push(name);
  47. //std::unique_lock<std::mutex> uni(module::timer::getInstance()->m_mutex);
  48. //module::timer::getInstance()->m_list.erase(name);
  49. }
  50. void module::timer::regist(sol::state* lua)
  51. {
  52. lua->new_usertype<module::timer>("timer",
  53. "add", &module::timer::add,
  54. "remove", &module::timer::remove
  55. );
  56. }
  57. module::timer::timer()
  58. {
  59. ::ithread::start();
  60. }
  61. bool module::timer::run()
  62. {
  63. auto comp_wait_msec = [&]()->timestamp {
  64. timestamp wait_msec = 0;
  65. auto now_msec = time::now_msec();
  66. std::unique_lock<std::mutex> uni(m_mutex);
  67. for_iter(iter, m_list)
  68. {
  69. if (iter->second.exec_msec <= now_msec)
  70. return 0;
  71. if (iter->second.exec_msec - now_msec < wait_msec || wait_msec == 0)
  72. wait_msec = iter->second.exec_msec - now_msec;
  73. }
  74. if (wait_msec == 0)
  75. return 1000;
  76. return wait_msec;
  77. };
  78. auto exec_func = [&](timer_info& ti)->bool {
  79. std::string exception_string;
  80. try
  81. {
  82. // 加载LUA文件
  83. if (ti.lua == nullptr)
  84. {
  85. ti.lua = sStateMgr->get();
  86. auto lbResult = ti.lua->state->load_file(ti.filepath);
  87. if (lbResult.valid() == false)
  88. {
  89. sol::error err = lbResult;
  90. throw ylib::exception("Failed to load script, " + std::string(err.what()));
  91. }
  92. lbResult();
  93. }
  94. // 加载函数
  95. if (ti.funname != "" && ti.function.valid() == false)
  96. ti.function = (*ti.lua->state)[ti.funname];
  97. // 执行函数
  98. if (ti.function.valid())
  99. {
  100. auto result = ti.function();
  101. if (!result.valid()) {
  102. sol::error err = result;
  103. throw ylib::exception(err.what());
  104. }
  105. bool rd = result;
  106. return rd;
  107. }
  108. }
  109. catch (const std::exception& e)
  110. {
  111. exception_string = e.what();
  112. if (sConfig->website.debug)
  113. LOG_ERROR("[timer][" + ti.filepath + "]: " + e.what());
  114. return false;
  115. }
  116. return false;
  117. };
  118. // 获取等待时间
  119. auto wait_msec = comp_wait_msec();
  120. for (size_t i = 0; i < wait_msec/10; i++)
  121. {
  122. if (module::timer::getInstance()->m_insert)
  123. break;
  124. system::sleep_msec(10);
  125. }
  126. module::timer::getInstance()->m_insert = false;
  127. std::unique_lock<std::mutex> uni(m_mutex);
  128. auto now_msec = time::now_msec();
  129. for (auto iter = m_list.begin(); iter != m_list.end();)
  130. {
  131. if (iter->second.exec_msec <= now_msec)
  132. {
  133. bool ready_remove = false;
  134. if (exec_func(iter->second) == false)
  135. ready_remove = true;
  136. if (ready_remove == false)
  137. {
  138. if (iter->second.loop == false)
  139. ready_remove = true;
  140. else
  141. {
  142. iter->second.exec_msec = now_msec + iter->second.msec;
  143. }
  144. }
  145. if (ready_remove)
  146. iter = m_list.erase(iter);
  147. else
  148. iter++;
  149. }
  150. else
  151. iter++;
  152. }
  153. std::string name;
  154. while (m_removed.pop(name))
  155. {
  156. auto iter = m_list.find(name);
  157. if (iter != m_list.end())
  158. {
  159. iter->second.lua->state->collect_garbage();
  160. sStateMgr->push(iter->second.lua);
  161. m_list.erase(iter);
  162. }
  163. }
  164. return true;
  165. }