Actor not remembering state

71 Views Asked by At

I am trying to create a sample application that monitors key strokes from scala on a windows machine using the jNativeHook library.

I have the following listener that listens for events,

object KeyListener extends org.jnativehook.keyboard.NativeKeyListener {

  val keyPressedActor = implicitly[ActorSystem].actorOf(Props[KeyPressedActor](), "KeyPressedActor")

  def nativeKeyPressed(event: NativeKeyEvent): Unit = {
    keyPressedActor ! event    
  }
 //blank override two more methods.
}

The main driver app that plugs the listener,

object ConsoleApp extends App {
  try {
    GlobalScreen.registerNativeHook();
    GlobalScreen.addNativeKeyListener(KeyListener)
  } catch {
    case nativehookException: NativeHookException => System.out.println("Encountered error while Hooking to global screen" + nativehookException.fillInStackTrace())
    case ex: Exception                            => System.out.println("Miserable ! Shouldn't have happened ." + ex.fillInStackTrace())
  }
}

And this is the implementation of the actor that i want to store the key strokes in some collection,

class KeyPressedActor extends Actor {
  var testQueue = new scala.collection.mutable.Queue[String]()

  def receive = {
    case event: NativeKeyEvent =>

      if (event.paramString().contains("modifiers=Ctrl")) {
         testQueue.enqueue("this_is_test")        
      }

    case _ => System.out.println("Bummer !  You are NOT supposed to see THIS !")
  }
}

Now i am seeing each time the actor enters the block where we add a string to the queue it does not remember the last element that got inserted into it.

I cannot understand why this is happening. This problem is not seen if i just have a Main app that sends messages to the actor. I cannot put a finger on why this is happening.


Update :

Actually there is something else going on with the code in a section i did not copy here initially. So if i have this inside the if block of the actor ,

NativeKeyEvent.getKeyText(event.getKeyCode) match {
          case "C" =>   
                        isCPressed = true
          case "V" => isVPressed = true
          case "N" => isNPressed = true

this behavior is observed. I changed this code to this ,

 val keyCode = NativeKeyEvent.getKeyText(event.getKeyCode)

        if (keyCode.equalsIgnoreCase("c")) {
         testQueue.enqueue("this_is_test")
        }

I wonder if this means that the match statement is running on some different context/thread ???

0

There are 0 best solutions below