| #ifndef _RIVE_KEY_FRAME_HPP_ |
| #define _RIVE_KEY_FRAME_HPP_ |
| #include "rive/generated/animation/keyframe_base.hpp" |
| namespace rive |
| { |
| class KeyFrame : public KeyFrameBase |
| { |
| public: |
| inline float seconds() const { return m_seconds; } |
| |
| void computeSeconds(int fps); |
| |
| StatusCode import(ImportStack& importStack) override; |
| |
| #ifdef WITH_RIVE_EDITOR |
| // Edit-time only. Mirrors Dart's `KeyFrame.frameChanged` / |
| // `KeyFrame.updateSeconds` (rive_core/lib/animation/keyframe.dart). |
| // When the user (or coop) writes a new `frame` value through the |
| // generated setter, we resolve the parent chain (KeyedProperty → |
| // KeyedObject → LinearAnimation), recompute `m_seconds = frame / |
| // animation.fps`, and tell the parent KeyedProperty its order is |
| // dirty so the editor list is re-sorted before the next apply. |
| // |
| // The runtime build *never* compiles this override — under runtime |
| // builds the base class's empty `frameChanged()` no-ops, since |
| // runtime keyframes are imported once and `m_seconds` is locked in |
| // by `computeSeconds(fps)` from `keyed_property_importer.cpp`. |
| // This keeps the runtime hot path free of the parent-chain walk. |
| void frameChanged() override; |
| #endif |
| |
| private: |
| float m_seconds; |
| }; |
| } // namespace rive |
| |
| #endif |