frame_list.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * frame_list.cpp - node that switches between its children in time
  3. * Copyright (C) 2017 caryoscelus
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <core/node_info.h>
  19. #include <core/node/proxy_node.h>
  20. #include <core/all_types.h>
  21. #include <core/context.h>
  22. namespace rainynite::core {
  23. namespace nodes {
  24. template <typename T>
  25. class Frame : public Node<TimePointType> {
  26. public:
  27. Frame() {
  28. this->template init<T>(value, {});
  29. this->template init<Time>(time, {});
  30. }
  31. public:
  32. TimePointType get(shared_ptr<Context> /*ctx*/) const override {
  33. return {};
  34. }
  35. private:
  36. NODE_PROPERTY(value, T);
  37. NODE_PROPERTY(time, Time);
  38. };
  39. NODE_INFO_TEMPLATE(Frame, Frame<T>, TimePointType);
  40. TYPE_INSTANCES(FrameNodeInfo)
  41. template <class T>
  42. class FrameList : public ProxyNode<T> {
  43. public:
  44. FrameList() {
  45. this->template init_list<TimePointType>(frame_list);
  46. this->template init<T>(default_value, {});
  47. // TODO: don't do this here?
  48. this->get_frame_list()->new_id();
  49. }
  50. public:
  51. NodeInContext get_proxy(shared_ptr<Context> ctx) const override {
  52. auto aframes = list_frame_list()->get_links();
  53. vector<TimePoint<T>> frames;
  54. std::transform(
  55. std::begin(aframes),
  56. std::end(aframes),
  57. std::back_inserter(frames),
  58. [ctx](auto frame) -> TimePoint<T> {
  59. if (auto f = dynamic_pointer_cast<Frame<T>>(frame))
  60. return { f->get_time()->get(ctx), f->get_value() };
  61. return { Time::infinity(), nullptr };
  62. }
  63. );
  64. std::sort(
  65. std::begin(frames),
  66. std::end(frames),
  67. [](auto a, auto b) -> bool {
  68. return a.time < b.time;
  69. }
  70. );
  71. auto time = ctx->get_time();
  72. TimePoint<T> const* last = nullptr;
  73. for (auto const& frame : frames) {
  74. if (!frame.value)
  75. continue;
  76. if (frame.time == time)
  77. return {frame.value, ctx};
  78. if (frame.time > time)
  79. break;
  80. last = &frame;
  81. }
  82. if (last)
  83. return {last->value, ctx};
  84. return {get_default_value(), ctx};
  85. }
  86. private:
  87. NODE_LIST_PROPERTY(frame_list, TimePointType);
  88. NODE_PROPERTY(default_value, T);
  89. };
  90. NODE_INFO_TEMPLATE(FrameList, FrameList<T>, T);
  91. TYPE_INSTANCES(FrameListNodeInfo)
  92. } // namespace nodes
  93. } // namespace rainynite::core