Guest User

Compile-Time recursion

a guest
Sep 30th, 2015
65
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <SFML/System.hpp>
  2.  
  3. template <typename T>
  4. struct SingleUpdater {
  5.     T& system;
  6.     sf::Time total;
  7.    
  8.     SingleUpdater(T& system)
  9.         : system{system}
  10.         , total{sf::Time::Zero} {
  11.     }
  12.    
  13.     void update(sf::Time const & elapsed) {
  14.         sf::Clock clock;
  15.         system.update(elapsed);
  16.         total += clock.restart();
  17.     }
  18. };
  19.  
  20. template <typename... Tail>
  21. struct MultiUpdater;
  22.  
  23. template <typename Head, typename... Tail>
  24. struct MultiUpdater<Head, Tail...>
  25.     : MultiUpdater<Tail...>
  26.     , SingleUpdater<Head> {
  27.    
  28.     MultiUpdater(Head& head, Tail& ...args)
  29.         : MultiUpdater<Tail...>{std::forward<Tail&>(args)...}
  30.         , SingleUpdater<Head>{std::forward<Head&>(head)} {
  31.     }
  32.    
  33.     void update(sf::Time const & elapsed) {
  34.         SingleUpdater<Head>::update(elapsed);
  35.         MultiUpdater<Tail...>::update(elapsed);
  36.     }
  37. };
  38.  
  39. template <>
  40. struct MultiUpdater<> {
  41.     MultiUpdater() {}
  42.    
  43.     void update(sf::Time const & elapsed) {}
  44. };
  45.  
  46. template <typename... Args>
  47. struct EntityUpdater
  48.     : MultiUpdater<Args...> {
  49.    
  50.     EntityUpdater(Args& ...args)
  51.         : MultiUpdater<Args...>{std::forward<Args&>(args)...} {
  52.     }
  53.    
  54.     template <typename T>
  55.     sf::Time& getTotal() {
  56.         return SingleUpdater<T>::total;
  57.     }
  58. };
  59.  
  60. // ---------------------------------------------------------------------------
  61.  
  62. #include <iostream>
  63. #include <thread>
  64.  
  65. struct SystemA {
  66.     void update(sf::Time const & elapsed) {
  67.         std::cout << "SystemA::update(" << elapsed.asMilliseconds() << "ms)\n";
  68.         std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(5));
  69.     }
  70. };
  71.  
  72. struct SystemB {
  73.     void update(sf::Time const & elapsed) {
  74.         std::cout << "SystemB::update(" << elapsed.asMilliseconds() << "ms)\n";
  75.         std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(15));
  76.     }
  77. };
  78.  
  79. struct SystemC {
  80.     void update(sf::Time const & elapsed) {
  81.         std::cout << "SystemC::update(" << elapsed.asMilliseconds() << "ms)\n";
  82.         std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(3));
  83.     }
  84. };
  85.  
  86. struct SystemD {
  87.     void update(sf::Time const & elapsed) {
  88.         std::cout << "SystemD::update(" << elapsed.asMilliseconds() << "ms)\n";
  89.         std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(8));
  90.     }
  91. };
  92.  
  93. int main() {
  94.     SystemA a;
  95.     SystemB b;
  96.     SystemC c;
  97.     SystemD d;
  98.    
  99.     EntityUpdater<SystemA, SystemD, SystemB, SystemC> updater{a, d, b, c};
  100.     updater.update(sf::milliseconds(20));
  101.     updater.update(sf::milliseconds(19));
  102.     updater.update(sf::milliseconds(23));
  103.     updater.update(sf::milliseconds(30));
  104.     updater.update(sf::milliseconds(12));
  105.     updater.update(sf::milliseconds(20));
  106.    
  107.     std::cout << "Total time for System A: " << updater.getTotal<SystemA>().asMilliseconds() << "ms\n";
  108.     std::cout << "Total time for System B: " << updater.getTotal<SystemB>().asMilliseconds() << "ms\n";
  109.     std::cout << "Total time for System C: " << updater.getTotal<SystemC>().asMilliseconds() << "ms\n";
  110.     std::cout << "Total time for System D: " << updater.getTotal<SystemD>().asMilliseconds() << "ms\n";
  111. }
RAW Paste Data