Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复调用 delay_ms 时出现帧率误差较大的问题 #257

Merged
merged 1 commit into from
Feb 3, 2025

Conversation

yixy-only
Copy link
Collaborator

@yixy-only yixy-only commented Feb 3, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced graph update logic to ensure efficient and timely UI refreshes.
    • Introduced adjustable frame rate controls for smoother performance and consistent animation speed.
  • Refactor

    • Overhauled frame rate calculation and delay processing mechanisms to improve responsiveness and overall UI performance.

@yixy-only yixy-only self-assigned this Feb 3, 2025
Copy link

coderabbitai bot commented Feb 3, 2025

Walkthrough

The pull request introduces new function declarations and refactors existing functions across several files. In src/ege_graph.h and src/ege_time.h, functions for graph updates and frame rate control are added. In src/eggegapi.cpp, the frame rate calculation has been refactored by removing the old private FPS function and adding updateFrameRate and resetFrameRate, with getfps now returning a static frame rate. In src/graphics.cpp, the update logic is enhanced by modifying graphupdate and adding needToUpdate. Finally, src/time.cpp updates the delay functions to incorporate a new sleep-based mechanism along with UI and graph updates.

Changes

File(s) Change Summary
src/ege_graph.h Added two function declarations in the ege namespace: bool needToUpdate(_graph_setting* pg) and int graphupdate(_graph_setting* pg).
src/ege_time.h Added a new function: void updateFrameRate(bool addFrameCount = true) in the ege namespace.
src/eggegapi.cpp Removed EGE_PRIVATE_GetFPS; added updateFrameRate and resetFrameRate for frame rate calculation; updated getfps to return a static frame rate.
src/graphics.cpp Modified graphupdate: changed return type (no longer static) and integrated a call to needToUpdate; added a new bool needToUpdate(_graph_setting* pg) function; adjusted frame rate update calls with boolean visibility.
src/time.cpp Refactored delay_ms to compute a target time, use ege_sleep for waiting, and include calls to guiupdate and graphupdate; updated delay_fps and delay_jfps to forward to double overloads.

Sequence Diagram(s)

sequenceDiagram
    participant Frame as Frame Render Event
    participant Updater as updateFrameRate()
    participant State as Frame Rate State
    Frame->>Updater: call updateFrameRate(addFrameCount)
    Updater->>State: update frame count & elapsed time
    alt Elapsed time > 0.5 sec
        Updater->>State: calculate and update frame rate
    else
        Updater-->>Frame: no update performed
    end
    Frame->>Updater: call getfps()
Loading
sequenceDiagram
    participant Caller as UI/Event Loop
    participant Delay as delay_ms()
    participant Sleep as ege_sleep()
    participant GUI as guiupdate()
    participant Graph as graphupdate()
    Caller->>Delay: call delay_ms(ms)
    Delay->>Delay: calculate targetTime
    alt Current time < targetTime
        Delay->>Sleep: sleep for remaining time
    end
    Delay->>GUI: invoke guiupdate()
    Delay->>Graph: invoke graphupdate(pg)
Loading

Poem

I'm a rabbit, hopping through the code,
New functions and refactors lighten my abode.
Frame rates update with a rhythmic beat,
Delays and sleeps make the rhythm sweet.
With each change, I bound and leap—
Celebrating updates that make our code complete!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/time.cpp (2)

73-73: Watch out for potential floating-point precision issues.
While storing the target delay time as a double is fine for most use cases, consider edge cases or large values of ms that could lead to precision loss.


91-94: Consider logging or validating negative ms inputs.
Currently, negative ms is silently ignored. If this is intentional, it's fine; otherwise, you could log or raise an error to alert callers of invalid arguments.

src/ege_time.h (1)

9-10: Add some documentation to updateFrameRate.
Consider adding a comment to explain how this function impacts the frame rate logic and what the addFrameCount parameter does.

src/ege_graph.h (1)

25-28: Add documentation for the new functions.
Both needToUpdate and graphupdate would benefit from brief doc comments explaining their expected usage and return values, enhancing maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95b30ab and 1203fb9.

📒 Files selected for processing (5)
  • src/ege_graph.h (1 hunks)
  • src/ege_time.h (1 hunks)
  • src/egegapi.cpp (1 hunks)
  • src/graphics.cpp (2 hunks)
  • src/time.cpp (3 hunks)
🧰 Additional context used
🪛 Cppcheck (2.10-2)
src/graphics.cpp

[error] 199-199: Signed integer overflow for expression '0xFF<<24'.

(integerOverflow)

🔇 Additional comments (16)
src/time.cpp (10)

63-66: Good job adding descriptive doc comments.
These lines provide clarity about the function's purpose and parameters, improving maintainability.


75-76: Doc comment and GUI update call look fine.
The inline documentation clarifies when and why guiupdate is invoked, which is helpful for future maintainers.


78-82: Verify pointer safety for root.
If pg->egectrl_root could ever be null, this sequence would dereference a null pointer. Ensure it's never null or add a safeguard check.


84-84: Clear inline documentation for delay section.
This comment block accurately describes the delay logic and helps new contributors quickly grasp the intention.


85-88: Using Sleep(0) to yield the CPU is acceptable.
This approach relinquishes CPU time on zero-millisecond requests while still performing event handling immediately afterward.


104-107: Integer overload for delay_fps looks good.
Forwarding the call to the double-based implementation ensures consistent behavior and avoids duplicated code.


109-112: long overload maintains consistency.
Again, forwarding to the double-based version is a clean approach for code reuse.


157-160: Integer overload for delay_jfps follows the same pattern.
This helps preserve uniform logic and consistent usage hints across the codebase.


162-165: long overload for delay_jfps is structured consistently.
No issues here; the approach mirrors your other overload designs.


198-198: Clarify why updateFrameRate(false) is used.
Calling updateFrameRate(false) omits incrementing the frame count. Verify that this is intentional and does not cause unintended behavior in FPS calculations.

src/graphics.cpp (2)

185-188: LGTM! Good encapsulation of update conditions.

The function nicely encapsulates the update conditions into a reusable function, improving code readability.


190-230: LGTM! Improved frame rate handling based on window visibility.

The function now correctly handles frame rate updates by:

  1. Incrementing frame count only when the window is visible
  2. Still updating frame rate when window is not visible, but without incrementing frame count

This change helps fix frame rate deviation issues by ensuring accurate frame counting.

🧰 Tools
🪛 Cppcheck (2.10-2)

[error] 199-199: Signed integer overflow for expression '0xFF<<24'.

(integerOverflow)

src/egegapi.cpp (4)

3061-3064: LGTM! Well-structured frame rate tracking variables.

The static variables are well-named and provide clear separation of concerns for frame rate tracking.


3071-3098: LGTM! Robust frame rate calculation implementation.

The function implements a solid frame rate calculation strategy:

  1. Uses 0.5s update periods for stable measurements
  2. Separates frame counting from timing updates
  3. Uses high-precision timer for accurate timing

This implementation helps fix frame rate deviation issues by providing more accurate and stable measurements.


3100-3106: LGTM! Clean frame rate state reset.

The function properly resets all frame rate tracking variables to their initial states.


3108-3111: LGTM! Efficient frame rate access.

The function now efficiently returns the pre-calculated frame rate instead of computing it on each call.

@yixy-only
Copy link
Collaborator Author

当 delay_ms 延时较长时,内部可能会进行多次交换帧缓冲操作,每次都会计一次帧数,造成帧率变大。因此调整 delay_ms 行为,只进行一次交换帧缓冲操作。
delay_ms 每次调用时会需要交换帧缓冲,但参数 ms 不同值时有不同行为:ms < 0 时不延时, ms = 0 时调用 Sleep(0),让出 CPU 时间片,处理后立即返回。 ms > 0 时正常延时(由于交换帧缓冲本身需要时间,如果延时时间较短使得交换后已超出目标时间,而直接返回不再额外延时)。

@yixy-only
Copy link
Collaborator Author

在延时里面更新 GUI 属实不妥,GUI 在应用层次应该是更上层的东西,在这里插入有点混乱,GUI 层应该自己提供更新接口, 由用户调用。等后面加入新的UI库后再将其去除。

@yixy-only yixy-only merged commit 5978ca1 into wysaid:master Feb 3, 2025
2 checks passed
@yixy-only yixy-only deleted the fix_fps branch February 3, 2025 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant