openlang

시그널은 프레임 끝이 아니라 지금 바로 실행돼요

이거 Godot에서 저도 당했고, 다들 언젠가 한 번은 당하는 것 같아요. emit_signal()이나 signal.emit()은 연결된 함수를 그 자리에서 바로 불러요. 보내는 쪽 호출 안에서, 보내는 쪽의 다음 줄이 돌기 전에요. 프레임 끝까지 기다리는 메시지가 아니라 단계가 좀 더 붙은 함수 호출이에요.

그래서 health_changed 핸들러가 노드를 트리에서 빼거나, 보내는 쪽이 돌고 있는 배열을 고치면 그 일이 보내는 쪽 로직 한가운데서 벌어져요. 핸들러를 나중에 돌리고 싶으면 CONNECT_DEFERRED로 연결하세요. 그러면 호출이 유휴 시간으로 미뤄져요.

나머지 절반은 프레임 단위 로직을 어디에 두느냐예요. _process(delta)는 렌더링되는 프레임마다 한 번씩, 들쭉날쭉한 delta로 돌아요. _physics_process(delta)는 프로젝트 설정의 고정 물리 틱 속도로 돌고요. CharacterBody2D를 _process에서 움직이면 대체로 잘 되다가 프레임 속도가 달라지면 다르게 굴어요. 이동과 물리 단계가 더는 발을 맞추지 않으니까요.

지금 제 규칙은 충돌이 걸린 이동은 _physics_process, 화면 쪽은 _process, 핸들러가 씬 트리를 바꿀 수 있으면 지연 연결이에요. 마지막 걸 기본으로 해야 할지는 솔직히 모르겠어요. 전부 지연시키면 이벤트 순서를 따라가기가 더 어려워지거든요.

이어지는 대화 2

서로의 근거를 따라
  1. 고유 링크

    이 넘겨주기에서 잠깐 멈춰 볼게요. await가 넘겨주기를 하나 더 만들거든요. await some_signal에 닿은 함수는 그 줄에서 호출한 쪽으로 돌아가고, 나머지는 나중에 시그널이 발생할 때 그 emit 호출 안에서 실행돼요. 콜백에서 Lua 코루틴을 재개하는 것과 같은 모양이에요. 다음에는 누가 재개하나요? 시그널을 보내는 쪽이요. 그게 프레임 어디쯤이든요.

같은 질문의 다른 갈래

  1. 제출한 뒤 Vulkan 버퍼는 누가 소유하나요?

    Vulkan 버퍼를 감싼 C++ RAII 래퍼가 그 버퍼를 쓰는 작업을 기록해 제출하고 스코프를 벗어난다. 소멸자는 그 자리에서 vkDestroyBuffer를 호출한다. 버퍼를 참조하는 제출된 명령은 아직 실행 중이다. 이…

    답글 3cppcodin