Signed-off-by: myperworld <myperworld@126.com>
This commit is contained in:
1 parent
0986832fd1
commit
aacd052c06
3403 files changed
+597376
-12
No files matched your search
@@ -0,0 +1,187 @@
|
||||
#pragma once
|
||||
|
||||
/// @file time.h
|
||||
/// @brief Universal timing functions for FastLED
|
||||
///
|
||||
/// This header provides a universal `fl::time()` function that works consistently
|
||||
/// across all FastLED-supported platforms. It abstracts away platform-specific
|
||||
/// timing implementations and provides a clean, testable API.
|
||||
///
|
||||
/// @section Basic Usage
|
||||
/// @code
|
||||
/// #include "fl/time.h"
|
||||
///
|
||||
/// void loop() {
|
||||
/// fl::u32 now = fl::time();
|
||||
///
|
||||
/// // Use timing for animations
|
||||
/// static fl::u32 last_update = 0;
|
||||
/// if (now - last_update >= 16) { // ~60 FPS
|
||||
/// update_animation();
|
||||
/// last_update = now;
|
||||
/// }
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// @section Testing Support
|
||||
/// For unit testing, time injection is available:
|
||||
/// @code
|
||||
/// #ifdef FASTLED_TESTING
|
||||
/// #include "fl/time.h"
|
||||
///
|
||||
/// TEST(AnimationTest, TimingTest) {
|
||||
/// fl::MockTimeProvider mock(1000);
|
||||
/// fl::inject_time_provider(mock);
|
||||
///
|
||||
/// EXPECT_EQ(fl::time(), 1000);
|
||||
///
|
||||
/// mock.advance(16);
|
||||
/// EXPECT_EQ(fl::time(), 1016);
|
||||
///
|
||||
/// fl::clear_time_provider();
|
||||
/// }
|
||||
/// #endif
|
||||
/// @endcode
|
||||
|
||||
#include "fl/namespace.h"
|
||||
#include "fl/int.h"
|
||||
|
||||
#ifdef FASTLED_TESTING
|
||||
#include "fl/function.h"
|
||||
#endif
|
||||
|
||||
namespace fl {
|
||||
|
||||
/// Universal millisecond timer - returns milliseconds since system startup
|
||||
///
|
||||
/// This function provides consistent timing across all FastLED platforms:
|
||||
/// - Arduino/AVR: Hardware timer-based millis()
|
||||
/// - ESP32/ESP8266: ESP-IDF timing functions
|
||||
/// - ARM: Platform-specific ARM timers
|
||||
/// - WASM: JavaScript-based timing
|
||||
/// - Native/Testing: std::chrono implementation
|
||||
/// - Stub: Fake timer for testing
|
||||
///
|
||||
/// @return Number of milliseconds since the system started
|
||||
/// @note Wraps around approximately every 49.7 days (2^32 milliseconds)
|
||||
/// @note This function is designed to be zero-overhead - it compiles to a direct
|
||||
/// platform call in optimized builds
|
||||
///
|
||||
/// @section Platform Behavior
|
||||
/// - **Consistent**: All platforms return milliseconds since startup/initialization
|
||||
/// - **Monotonic**: Time always increases (except on wraparound)
|
||||
/// - **Resolution**: 1 millisecond resolution on all platforms
|
||||
/// - **Wraparound**: Consistent wraparound behavior at 2^32 milliseconds
|
||||
///
|
||||
/// @section Usage Examples
|
||||
/// @code
|
||||
/// // Basic timing
|
||||
/// fl::u32 start = fl::time();
|
||||
/// do_work();
|
||||
/// fl::u32 elapsed = fl::time() - start;
|
||||
///
|
||||
/// // Animation timing
|
||||
/// static fl::u32 last_frame = 0;
|
||||
/// fl::u32 now = fl::time();
|
||||
/// if (now - last_frame >= 16) { // 60 FPS
|
||||
/// render_frame();
|
||||
/// last_frame = now;
|
||||
/// }
|
||||
///
|
||||
/// // Timeout handling
|
||||
/// fl::u32 timeout = fl::time() + 5000; // 5 second timeout
|
||||
/// while (fl::time() < timeout && !is_complete()) {
|
||||
/// process_step();
|
||||
/// }
|
||||
/// @endcode
|
||||
fl::u32 time();
|
||||
|
||||
#ifdef FASTLED_TESTING
|
||||
|
||||
/// Type alias for time provider functions used in testing
|
||||
using time_provider_t = fl::function<fl::u32()>;
|
||||
|
||||
/// Inject a custom time provider for testing
|
||||
///
|
||||
/// This function allows unit tests to control the timing returned by fl::time().
|
||||
/// Once injected, all calls to fl::time() will use the provided function instead
|
||||
/// of the platform's native timing.
|
||||
///
|
||||
/// @param provider Function that returns the current time in milliseconds
|
||||
/// @note Only available in testing builds (when FASTLED_TESTING is defined)
|
||||
/// @note Thread-safe: Uses appropriate locking in multi-threaded environments
|
||||
///
|
||||
/// @section Example Usage
|
||||
/// @code
|
||||
/// fl::MockTimeProvider mock(1000);
|
||||
/// fl::inject_time_provider(mock);
|
||||
///
|
||||
/// ASSERT_EQ(fl::time(), 1000);
|
||||
///
|
||||
/// mock.advance(500);
|
||||
/// ASSERT_EQ(fl::time(), 1500);
|
||||
///
|
||||
/// fl::clear_time_provider(); // Restore normal timing
|
||||
/// @endcode
|
||||
void inject_time_provider(const time_provider_t& provider);
|
||||
|
||||
/// Clear the injected time provider and restore platform default timing
|
||||
///
|
||||
/// After calling this function, fl::time() will return to using the platform's
|
||||
/// native timing implementation.
|
||||
///
|
||||
/// @note Only available in testing builds (when FASTLED_TESTING is defined)
|
||||
/// @note Thread-safe: Uses appropriate locking in multi-threaded environments
|
||||
/// @note Safe to call multiple times or when no provider is injected
|
||||
void clear_time_provider();
|
||||
|
||||
/// Mock time provider for controlled testing
|
||||
///
|
||||
/// This class provides a controllable time source for unit testing. It maintains
|
||||
/// an internal time value that can be advanced manually or set to specific values.
|
||||
///
|
||||
/// @section Example Usage
|
||||
/// @code
|
||||
/// fl::MockTimeProvider mock(1000); // Start at 1000ms
|
||||
/// fl::inject_time_provider(mock);
|
||||
///
|
||||
/// // Test timing-dependent code
|
||||
/// EXPECT_EQ(fl::time(), 1000);
|
||||
///
|
||||
/// mock.advance(100); // Advance by 100ms
|
||||
/// EXPECT_EQ(fl::time(), 1100);
|
||||
///
|
||||
/// mock.set_time(5000); // Jump to 5000ms
|
||||
/// EXPECT_EQ(fl::time(), 5000);
|
||||
///
|
||||
/// fl::clear_time_provider();
|
||||
/// @endcode
|
||||
class MockTimeProvider {
|
||||
public:
|
||||
/// Constructor with initial time value
|
||||
/// @param initial_time Starting time in milliseconds (default: 0)
|
||||
explicit MockTimeProvider(fl::u32 initial_time = 0);
|
||||
|
||||
/// Advance the mock time by the specified amount
|
||||
/// @param milliseconds Number of milliseconds to advance
|
||||
void advance(fl::u32 milliseconds);
|
||||
|
||||
/// Set the mock time to a specific value
|
||||
/// @param milliseconds New time value in milliseconds
|
||||
void set_time(fl::u32 milliseconds);
|
||||
|
||||
/// Get the current mock time
|
||||
/// @return Current time in milliseconds
|
||||
fl::u32 current_time() const;
|
||||
|
||||
/// Function call operator for use with inject_time_provider()
|
||||
/// @return Current time in milliseconds
|
||||
fl::u32 operator()() const;
|
||||
|
||||
private:
|
||||
fl::u32 mCurrentTime;
|
||||
};
|
||||
|
||||
#endif // FASTLED_TESTING
|
||||
|
||||
} // namespace fl
|
||||
Reference in new issue
Block a user