반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함


오늘은 우선 Function Listener와 Table Listener 에 대해서 알아보는 것으로 시작 하겠습니다.

local myListener = function( event )
        print( "Listener called with event of type " .. event.name )
end
Runtime:addEventListener( "touch", myListener )
Runtime:addEventListener( "enterFrame", myListener )

위 리스너는 function 리스너 입니다.
Runtime으로 시작했으니 Global 리스너네요. 하나는 touch에 걸고 다른 하나는 enterFrame에 리스너를 걸었습니다.
touch를 하면 "Listener called with event of type touch"가 나올것이고 가만히 있으면 touch대신 enterFrame이 계속 찍히게 될 겁니다.

두 이벤트 모두 myListener라는 함수를 호출하죠? 이건 함수 리스너입니다.
가끔 함수 리스너는 이 리스너가 발생할 때 특정 변수를 처리하는데 한계가 있습니다. 이럴 경우 object Listener (table Listener) 를 사용할 수 있습니다.

-- assume MyClass and MyClass:new() already exist
 
function MyClass:enterFrame( event )
        print( "enterFrame called at time: " .. event.time )
end
 
function MyClass:touch( event )
        print( "touch occurred at ("..event.x..","..event.y..")" )
end
 
local myObject = MyClass:new()
 
Runtime:addEventListener( "touch", myObject )
Runtime:addEventListener( "enterFrame", myObject )

object Listener 는 위와 같이 사용합니다.
(이 코드는 이미 MyClass가 생성 돼 있어야 실행 됩니다.)
처음 코드와 같이 Runtime으로 리스너를 달았지만 테이블 리스너를 사용해 MyClass:enterFrame, MyClass:touch 이렇게 특정 이벤트에 함수를 달기 때문에 enterFrame에만 있는 정보들 그리고 touch 에만 있는 정보들 등을 자유롭게 사용할 수 있습니다.

Runtime Events

Runtime Events에 대해 알아 보겠습니다.

enterFrame
이 enterFrame은 Runtime:addEventListener  API를 이용해서 작동시킬 수 있습니다. 각 frameTime마다 불려질 겁니다.

local myListener = function( event )
        print( "Listener called with event of type " .. event.name )
end
Runtime:addEventListener( "enterFrame", myListener )

아래와 같은 프로퍼티가 있습니다.
event.name : enterFrame 이라는 스트링이 반환 됩니다.
event.time : 앱 시작 부터 지금 까지의 시간이 밀리세컨드로 표시 됩니다.

System

앱 실행 중에 전화가 온다든가 하는 이유로 다른 일을 할 동안 앱이 계속 유지 되게 하는데 필요합니다.
아래와 같은 프로퍼티들이 있습니다.
event.name : system 스트링 반환
event.type - 아래와 같은 스트링이 반환됩니다.
 : applicationStart - 앱이 시작될 때 그리고 main.lua에ㅔ 있는 모든 코드가 실행 됐을 때 발생함
 : applicationExit - 유저가 앱을 끝낼때 실행 됨
 : applicationSuspend - 전화가 오거나 오랫동안 사용을 안 해서 화면이 까맣게 될 때 같이 앱이 계속 유지될 필요가 있을 때 발생합니다.
 : applicationResume - 앱이 다시 실행 될 때 발생합니다. 시뮬레이터에서는 시뮬레이터가 백그라운드에 있다가 다시 포그라운드로 올라 올 때 실행 됩니다.

Orientation

지난 시간에 예제를 통해서 봤는데요. 전화기의 방향이 바뀔 때 이벤트들이 발생합니다.
아래와 같은 프로퍼티들이 있습니다.
event.name : orientation
event.type : portrait, landscapeLeft, portraitUpsideDown, landscapeRight, faceUp, faceDown

accelerometer

이것은 전화기를 기울이는 대로 중력이 작용하도록 할 때 사용합니다.(제 경험상)
아래와 같은 프로퍼티들이 있습니다.
event.name : accelerometer
event.xGravity : x 축 의 중력 관련 가속도 acceleration
event.yGravity : y 축의 중력 관련
event.zGrabity : z 축의 중력 관련
event.xInstant : x 축의 순간 가속도 instantaneous
event.yInstant : y 축의 순간 가속도
event.zInstant : z 축의 순간 가속도
event.isShake : 전화기를 흔들어쓸 때

location (GPS)

GPS 하드웨어에 의해 발생되는 위치 이벤트 입니다.
event.name : location
event.latitude : 위도
event.longitude : 경도
event.altitude : 고도
event.accuracy : 정확도(몇 미터를 기준으로 파악할지 여부)
event.speed : 초당 미터 m/s 로 나타나는 순간 스피드
event.direction : 북쪽부터 시작하는 시계방향으로의 방향
event.time : location event의 UTC timestamp

에러가 났을 경우에는 아래 프로퍼티에 어떤 값이 할당 됩니다.
event.errorMessage : error description. 에러가 났을 때에만 나옵니다.
event.errorCode : 에러 메세지

heading (compass)

안드로이드에서는 event.magnetic 만 지원되고 event.geographic은 지원 되지 않습니다.
event.name : heading
event.geographic : geographic 북극을 기준으로 시계방향으로의 heading 방향
event.magnetic : magnetic 북극을 기준으로 시계방향으로의 heading 방향

memoryWarning

iOS에서만 지원되는 메모리 사용 관련 이벤트. 거의 5초 이내에 shut down 될 정도의 상황에서 발생.

local function handleLowMemory( event )
  print( "memory warning received!" )
end
 
Runtime:addEventListener( "memoryWarning", handleLowMemory )

Targeted Event

어떠한 단일 Target에 이벤트를 보냄

completion
오디오, 비디오 부분에서  예제로 다뤘었는데요. 오디오나 비디오가 완전히 끝났을 때 발생하는 이벤트 입니다.
event.name : completion

timer
event.name : timer
event.sorce : 타이머에 등록된 값
event.count : 타이머가 실행 된 횟수
event.time : 앱이 시작된 이후부터 지금까지의 시간

urlRequest

native.webPopup() 함수와 함께 등록되는 이벤트 입니다.
event.name : urlRequest
event.url : absolute URL
event.errorMessage : 에러 메세지 유저의 언어 세팅에 따라 표시 됨
event.errorCode : 에러 메세지 유저의 언어 세팅에 관계 없이 표시 됨

오늘은 빨리 작업할 일이 있어서 여기까지 밖에 정리하지 못하겠네요.
다음 시간에 Touch Events, Multi Touch Events 그리고 Timer에 대해 알아 보겠습니다.

감사합니다.

반응형

Comment

  1. 안녕하세요. 오랜만에 댓글을 남기는 것 같네요.
    솔웅님의 포스트들 덕분에 잘 코딩을 하고 있습니다.

    여쭤보고 싶은 것이 있는데 바로 event의 touch 이벤트입니다.
    제가 터치 이벤트를 Runtime으로 만들고 그 안에서
    터치 이벤트를 삭제하는 행위를 하는데요.
    실제로 해보니까 터치이벤트리스너가 삭제가 안되더라구요.
    자세한 내용은 밑의 소스를 보시는 것이 편하실 듯 합니다.
    (어렵지 않은 코드입니다.)


    local enterFrame1, enterFrame2
    local touch1, touch2

    local enterFrame1 = function( event )
    print ("enterFrame1")
    end

    local enterFrame2 = function( event )
    print ("enterFrame2")
    end

    local touch1 = function( event )
    if event.phase == "began" then
    Runtime:removeEventListener( "enterFrame", enterFrame1 )
    print ("touch1 began")
    end

    if event.phase == "ended" then
    Runtime:removeEventListener( "enterFrame", enterFrame2 )
    Runtime:removeEventListener( "touch", touch1 )
    print ("touch1 ended")
    end
    end

    local touch2 = function( event )
    if event.phase == "began" then
    print ("touch2 began")
    end

    if event.phase == "ended" then
    print ("touch2 ended")
    Runtime:removeEventListener( "touch", touch2 )
    end
    end

    Runtime:addEventListener( "enterFrame", enterFrame1 )

    Runtime:addEventListener( "enterFrame", enterFrame2 )

    Runtime:addEventListener( "touch", touch1 )
    Runtime:addEventListener( "touch", touch2 )

    • 솔웅 2012.01.31 13:38 신고

      예 제가 해 봐도 Runtime-enterFrame은 Remove되는 것 같은데 Runtime-touch는 Remove가 안 되네요.
      그런데 touch 이벤트를 Runtime에 걸지 않고 object에 걸면 어떨까요?
      배경이미지에 걸어도 되고......

  2. 혹시 A라는 그림 위에 B가 있고 A와 B에 터치 리스너를 걸어둔 다음
    B를 클릭하면 A까지 이벤트가 전달되나요? 혹은 B에는 터치 리스너를 등록하지 않고 A에만 등록해둔 다음 B를 터치하면 A에도 이벤트가 전달됩니까?

    • 솔웅 2012.02.01 13:11 신고

      예 리스너는 맨 위에 놓인 object를 체크하고 거기에 리스너가 없으면 그 밑에 있는 객체를 체크합니다. 그러다가 리스너가 없으면 계속 그 밑의 객체를 체크하는 식으로 동작합니다.
      그러니까 위에 있는 객체와 아래 있는 객체 모두 리스너가 달려 있으면 위에 있는 리스너만 작동합니다. 그리고 위 객체에 리스너가 없으면 아래 객체의 리스너가 작동합니다.
      만약 어떤 객체의 리스너에 우선순위를 주고 싶으면 그렇게 할 수도 있습니다.
      정확한 함수는 지금 기억이 안 나는데요. 그런 방법을 이 블로그에서 한번 다뤘던 기억이 납니다.
      찾아보시면 나올겁니다.

      제 글 '이벤트, 리스너로 다이나믹한 표현 하기 1'을 참고 하세요.
      그리고 'New, More Flexible ScrollView Widget'를 보시면 리스트뷰(테이블뷰) 에서 이벤트 리스너에 대한 takeFocus()함수도 참조하세요.

      감사합니다.