In the final project of Scene Graph, we have a function called func keyPressed(key: KeyboardControl, state: InputState) -> Bool where we updates the car’s position:
Scene’s update(deltaTime:) is called once per frame. It calls InputController’s updatePlayer(deltaTime:) which is where the position gets updated.
In a different thread, processEvent(key:state:) processes the keyboard input. directionKeysDown is a Set, so if you repeatedly press the w key, only one w value is retained.
InputController’s updatePlayer(deltaTime:) (being performed once per frame) takes that one w value and updates position.
Also, pressing a key is an I/O input signal sent to the CPU and has the lowest priority so it will be queued to be executed when all writes have finished. Also, CPU and GPU are so fast, that by the time you pressed w twice, multiple frames have already happened.
I see. What if the car’s position is updated in func updateScene(deltaTime: Float) for every frame, without pressing any key or triggering pan gestures?
These updates are triggered by Scene’s update(deltaTime:), which happens once per frame before the draw. Whether you set the position in updatePlayer(deltaTime:) or updateScene(deltaTime), it doesn’t make any difference.
Also, position itself is not passed to the GPU. It is part of the model matrix that is passed.
Also, commandBuffer.waitUntilCompleted() at the end of draw(in:), means that everything stops until the GPU finishes its render. This isn’t the best way to synchronize between CPU and GPU.
Triple buffering (introduced later in the book) will solve this.