If then in render loop high cpu usage

First of all, it really helps to run crystal tool format on your files, since inconsistently indented code like

      end
    end
  end
end
end
end
end
end

is pretty much guaranteed to confuse you at some point (and even more so others trying to read the code). There are many coding errors, which would’ve been prevented solely by correct indenting (for example, you’re only checking @@menu for "main", but not for "charselect".

The latter check is in the code, but only after @@menu is confirmed to be "main", so your check for "charselect" will always be false.

Also, your code is still displaying the window multiple times per frame if buttons are pressed - this indicates to me that you don’t really understand the code yourself - and this is also the reason why I recommended you (see Crsfml sprite texture not updating on it's own - #3 by MagicSparklyGoldfish) to simplify your code to the bare minimum first.

Keep in mind that you set your window to VSync, so every time you display the window, your program will not display another window until ~16.67 ms have passed. Multiple calls of window.display per frame will absolutely destroy your performance.

But to answer your initial question:

You are, in theory, creating one new fiber per frame. Each call of MenuElements.cursorFunc(window, @@menu) leads to a spawn do block, which then creates an infinite loop - so you’re essentially starting an increasing number of fibers that never stop.

I still STRONGLY recommend you to discard any concurrency entirely here, especially if you’re just starting to learn the language. Try to write a simple loop with completely separated logic, drawing and event handling. Something like this:

class Game
  @window : SF::RenderWindow

  def initialize
    @window = SF::RenderWindow.new(...) # Insert parameters here
    @window.vertical_sync_enabled = true
  end

  def run
    while @window.open?
      handle_events
      update
      draw
    end
  end

  def handle_events
    # Check events here, don't draw anything here
  end

  def update
    # Put your logic here, also no drawing here
  end

  def draw
    # Draw your stuff here - and nothing more
    @window.display # Render the window as the last thing to do
  end
end

Game.new.run

This simple model will bring so much clarity into your code and help you in avoiding annoying bugs. It will run perfectly fine, even without fibers (trust me - you REALLY don’t need them for 2D applications unless you make use of networking or heavy resource loading).

3 Likes