사용자:Hsl0/LinkTools

리버티게임, 모두가 만들어가는 자유로운 게임
< 사용자:Hsl0
imported>Hsl0님의 2023년 3월 27일 (월) 01:09 판 (→‎배경)

LinkTools와 EventTools는 가칭이므로 좋은 이름 추천해주면 감사하겠습니다. 글이 좀 지저분하지만 곧 정리할 예정입니다.

배경

링크를 인자로 받고 받은 링크를 수정하는 링크 틀이 늘어나면서, 이러한 틀을 합성할 필요성과 함께 여러 문제점이 발생하였다. 예를 들어 링크를 누르면 게임 데이터를 수정하는 DB2와, 뒤로가기가 가능한 이동을 수행하던 기본 링크 클릭 동작을 뒤로가기가 불가능한 이동으로 대체하는 일방통행링크는 모두 preventDefault()를 실행하고 링크 이동을 자체 구현한다. 일방통행링크는 원래 기본값을 수정해야 하는 것이고, DB2는 이벤트 기본값 동작이 비동기 동작을 기다려주지 않는 관계로 기본값 동작을 막고 직접 기본값 동작을 구현한다. 만약 이 둘을 사용하게 될 경우 두 틀을 작동시키는 이벤트 핸들러가 먼저 페이지 이동 동작을 실행하는 경쟁을 할 것이고, 경쟁에서 패배한 둘 중 하나는 동작하지 않을 것이다. 이렇게 기존 이벤트 핸들러는 비동기 동작을 기다려주지 않고, 독립적으로 등록된 핸들러가 기본 동작을 대체할 경우, 무엇이 실행될지 예측하기 어렵다. 이러한 문제점을 해결하기 위해 LinkTools(가칭)과 EventTools(가칭)을 개발하게 되었다.

이 프레임워크(?)는 입력을 받고 가공해서 내보내는 함수형 프로그래밍 철학을 기반으로 만들어졌다. 링크에 이벤트를 직접 배당하기보다는 링크를 재가공하는 함수에 집어넣는 느낌을 만들 수 있도록 하였다. 그리고 링크를 재가공하는 함수는 바로 틀이다. 따라서 클래스를 직접 사용하기 보다는 주로 틀 안에서 사용될 것이며, 틀로 사용하면 더 아름다운 모습이 나온다... 지만 그냥 기존에 쓰던 틀의 모습이다. 물론 직접 써도 된다. 자바스크립트를 부분적으로 사용하고 UI를 HTML로 구현하는 경우 직접 사용할 수도 있다.

LinkModifier와 EventTools는 밖에서 안으로, 또는 안에서 밖으로 실행되는 규칙이 있지만, 밖에 있는 함수는 입력으로 받은 링크가 어떤 링크인지 신경쓸 필요가 없다는 원칙에서 도출된 것이다. 그냥 링크가 존재하는지만 중요하며, LinkCreater를 쓰면 이 조차도 신경 쓸 필요가 없다. LinkModifier의 경우, 안쪽의 modifier가 먼저 링크를 수정하고 바깥쪽 modifier는 이미 수정된 링크를 받는 느낌이다. EventTools는 안쪽의 이벤트 listener/handler가 바깥쪽 listener/handler 관점에서 기본 동작이고, 바깥쪽 listener/handler가 기본 동작보다 먼저 실행되는 것이다. handler의 경우 기본값을 오버라이딩해서 기본값을 대체한다. 따라서 기본값은 실행하지 않는다. 기본 동작은 절대적이지 않고 상대적이며, 기본 동작은 꼭 DOM 표준만 되라는 법은 없고, 링크 수정 함수가 입력으로 받은 링크가 원래 하던 모든 행동들은 모두 기본 동작이라는 원칙에서 도출된 것이다. 기본값은 대단한 것이 아니라 그냥 다음에 실행될 이벤트 핸들러다.

구성요소

LinkModifier

  • 태그 안의 링크를 수정한다.
  • 안쪽이 먼저 실행되고 바깥쪽이 나중에 실행된다.
<span class="link-modifier" data-modifier"a">
    <span class="link-modifier" data-modifier="b">
        [[리버티게임:대문]]
    </span>
</span>

b 실행-a 실행

LinkCreater

  • link-slot-dummy: 태그 안에 아무런 링크가 없다면, 아무 기능이 없는href가 없고, 눌렀을 때 반응이 없는 링크(<a>)를 생성한다. EventTools와 함께 쓰면 좋다.
  • link-slot-dummy: 태그 안에 아무런 링크가 없다면, 현재 페이지를 가리키는href가 현재 페이지인 링크(<a>)를 생성한다. LinkModifier와 함께 쓰면 좋다.

EventTools

  • 이벤트를 비동기적으로 만든다.
  • 이벤트 handler/listener의 기본값을 재정의한다. 이벤트 handler/listener의 기본값은 안쪽에서 정의된 이벤트이다. (listener는 기존 listener/handler를 오버라이딩하지 않는다.)
  • listener는 (상대적) 기본값을 오버라이딩하지 않고, handler는 오버라이딩한다.
  • 바깥쪽이 먼저 실행되고 안쪽이 나중에 실행된다.
<span class="event-listener" data-target="link" data-listen-click="a">
    <span class="event-listener" data-target="link" data-listen-click="b">
        [[리버티게임:대문]]
    </span>
</span>

a 실행-b 실행-리버티게임:대문으로 이동 a에서는 기본 동작이 b 실행-리버티게임:대문으로 이동이다.

<span class="event-handler" data-target="link" data-handle-click='["a"]'>
    <span class="event-handler" data-target="link" data-handle-click='["b"]'>
        [[리버티게임:대문]]
    </span>
</span>

a 실행 a에서는 기본 동작이 b 실행-리버티게임:대문으로 이동이다. handler는 기본 동작을 실행시키지 않는다.

data-listen-(이벤트명)="(플래그) (동작)"
data-handle-(이벤트명)="(플래그) (동작)"
  • 이벤트 handler/listener는 기본적으로 동시에 실행되지만 다음 플래그는 이를 변경시킬 수 있다.
  • once는 처음 이벤트가 발생할 때 한번만 실행되고 그 이후 이벤트는 실행하지 않는다.
  • defer는 먼저 실행되는 listener/handler가 모두 작업을 완료했을 때 실행한다.
  • await는 다음에 실행되는 listener/handler가 이번 이벤트의 작업이 모두 완료될 때까지 기다린 후 실행되게 한다.
이번 이벤트 handler/listener 대기 여부
이전 / 이번 defer await defer await
즉시 대기 즉시 대기
defer 즉시 대기 즉시 대기
await 대기 대기 대기 대기
defer await 대기 대기 대기 대기
a
  defer ba 대기 후 실행
c
    defer da, b, c 대기 후 실행
e
await f
  gd 대기 후 실행
      await defer ha, b, c, d, e, f, g 대기 후 실행
        ia, b, c, d, e, f, g, h 대기 후 실행

이벤트 동작은 첫번째 요소가 동작 이름이고 나머지가 해당 동작의 인자인 JSON 배열으로, 다음과 같다.

["a", "b", 1, true, null, ["c"], {}]

이 때 a 동작이 실행되고 ["b", 1, true, null, ["c"], {}]가 인자로 제공된다.

도보시오