| 63 | |
| 64 | template <typename _ValueType> |
| 65 | void Track<_ValueType>::Allocate(size_t _keys_count, size_t _name_len) { |
| 66 | assert(ratios_.size() == 0 && values_.size() == 0); |
| 67 | |
| 68 | // Distributes buffer memory while ensuring proper alignment (serves larger |
| 69 | // alignment values first). |
| 70 | static_assert(alignof(_ValueType) >= alignof(float) && |
| 71 | alignof(float) >= alignof(uint8_t), |
| 72 | "Must serve larger alignment values first)"); |
| 73 | |
| 74 | // Compute overall size and allocate a single buffer for all the data. |
| 75 | const size_t buffer_size = _keys_count * sizeof(_ValueType) + // values |
| 76 | _keys_count * sizeof(float) + // ratios |
| 77 | (_keys_count + 7) * sizeof(uint8_t) / 8 + // steps |
| 78 | (_name_len > 0 ? _name_len + 1 : 0); |
| 79 | span<byte> buffer = {static_cast<byte*>(memory::default_allocator()->Allocate( |
| 80 | buffer_size, alignof(_ValueType))), |
| 81 | buffer_size}; |
| 82 | |
| 83 | // Fix up pointers. Serves larger alignment values first. |
| 84 | values_ = fill_span<_ValueType>(buffer, _keys_count); |
| 85 | ratios_ = fill_span<float>(buffer, _keys_count); |
| 86 | steps_ = fill_span<uint8_t>(buffer, (_keys_count + 7) / 8); |
| 87 | |
| 88 | // Let name be nullptr if track has no name. Allows to avoid allocating this |
| 89 | // buffer in the constructor of empty animations. |
| 90 | name_ = |
| 91 | _name_len > 0 ? fill_span<char>(buffer, _name_len + 1).data() : nullptr; |
| 92 | |
| 93 | assert(buffer.empty() && "Whole buffer should be consumned"); |
| 94 | } |
| 95 | |
| 96 | template <typename _ValueType> |
| 97 | void Track<_ValueType>::Deallocate() { |