Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (512)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  NullPointerException thrown from Poll() method  (Read 2846 times)
0 Members and 1 Guest are viewing this topic.
Offline astruyk

Senior Newbie





« Posted 2006-05-24 03:45:50 »

I've got a project using jInput for gamepad input. I rolled my own class to provide polling-update functionality (a thread that polls the controllers constantly for a change in button state) so that my classes can be notified when the state of one of the buttons changes on the gamepad. The problem is, that a few of my users are having troubles where a NullPointerException is being thrown (apparently) from the poll() method.

Here is the stacktrace:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
java.lang.NullPointerException
at net.java.games.input.DIControllers.getNextDeviceEvent(DIControllers.java:62)
at net.java.games.input.DIAbstractController.getNextDeviceEvent(DIAbstractController.java:62)
at net.java.games.input.AbstractController.poll(AbstractController.java:219)
at com.astruyk.freetar.input.Gamepad.updateButtonStates(Gamepad.java:123)
at com.astruyk.freetar.input.GamepadPoller.startPolling(GamepadPoller.java:91)
at com.astruyk.freetar.editor.MusicEditor.initButtonConfig(MusicEditor.java:561)
at com.astruyk.freetar.editor.MusicEditor.<init>(MusicEditor.java:111)
at com.astruyk.freetar.editor.MusicEditor.main(MusicEditor.java:2093)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.continueLaunch(Unknown Source)
at com.sun.javaws.Launcher.handleApplicationDesc(Unknown Source)
at com.sun.javaws.Launcher.handleLaunchFile(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)


the com.astruyk.freetar.* classes are my own. The initbuttonconfig() method in the Music Editor calls the GamepadPoller's startPolling() method, which activates javax.swing.Timer with the following intialization code:

1  
2  
3  
4  
5  
pollTimer = new Timer(POLL_TIME, new ActionListener(){
            public void actionPerformed(ActionEvent e){
                pollController();
            }
        });


The pollController() method calls the controllers poll() method (via a wrapper class - Gamepad) , and the exception is being thrown - at least, thats what I think is happening from the stackTrace.

I'm not familiar with the jInput code, and I was wondering if anyone might have any idea what is causing this issue, or what I might do to fix it for my users? For now I guess I'll just wrap the poll() in a try{}catch block for NullPointerException - but I thought I should report the issue anyways.
Offline endolf

JGO Coder


Medals: 7
Exp: 15 years


Current project release date: sometime in 3003


« Reply #1 - Posted 2006-05-24 12:17:13 »

Hi

I've looked at the jinput source where this is happening, and it looks like it can't map the object information in the event into a component. This is just a hash table lookup. It's possible that the poll is being called before the initialisation has finished, but I can't tell from the code you have provided.

Is your source available online somewhere?

I'm particularly interested in the following 2 lines and surrounding calls
1  
2  
at com.astruyk.freetar.input.Gamepad.updateButtonStates(Gamepad.java:123)
at com.astruyk.freetar.input.GamepadPoller.startPolling(GamepadPoller.java:91)


Cheers

Endolf

Offline astruyk

Senior Newbie





« Reply #2 - Posted 2006-05-24 16:22:21 »

Is your source available online somewhere?

I'm particularly interested in the following 2 lines and surrounding calls
1  
2  
at com.astruyk.freetar.input.Gamepad.updateButtonStates(Gamepad.java:123)
at com.astruyk.freetar.input.GamepadPoller.startPolling(GamepadPoller.java:91)


The full source isn't available at the moment anywhere, but here's the code you are interested in:

1  
2  
3  
4  
5  
6  
7  
8  
9  
    public synchronized void startPolling() {
        // Get the last state of all the components of the controller
        gamepad.poll();
        pressedLastUpdate.clear();
        for(Button currentButton : gamepad.getButtons()){
            pressedLastUpdate.put(currentButton, currentButton.isPressed());
        }
        pollTimer.start();
    }


Last night I refactored the gamepad.updateButtonStates() to gamepad.poll() to more closely match its intended functionality - so here's the source for the gamepad.poll()

1  
2  
3  
   public void poll(){
        controller.poll();
    }


Gamepad contains its own Controller Class - and also an array of Button objects associated with the gamepad.
Button is basically a wrapper for Component, with a couple subclasses so that I can handle analog and HAT-switch input as button presses rather than true-analog inputs. I had to create these classes so I could handle analog stick movements as button presses simply by calling .isPressed() rather than doing a bunch of checks each time for the type of Component I'm working with....

I'm not sure if you need it, but here's the code that the Timer calls when it is activated. It is in the GamepadPoller class (the class in charge of repeatedly polling the controller and generating events after button updates). This code is called by the Timer each time it runs.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
    public synchronized void pollController() {
        // Recheck the states of the components of the watched controller
        gamepad.poll();
        for (Button currentButton : pressedLastUpdate.keySet()) {
            if (pressedLastUpdate.get(currentButton) != currentButton.isPressed()) {
                ButtonEvent.EventType eventType = null;
                if (currentButton.isPressed()){
                    eventType = ButtonEvent.EventType.BUTTON_PRESSED;
                }else{
                    eventType = ButtonEvent.EventType.BUTTON_RELEASED;
                }
                ButtonEvent evt = new ButtonEvent(
                        gamepad,
                        currentButton,
                        eventType);
                for(GamepadButtonListener observer : observers){
                    observer.buttonActionTriggered(evt);
                }
                pressedLastUpdate.put(currentButton, currentButton.isPressed());
            }
        }
    }


As you can see, the ControllerPoller contains a Map<Button, Boolean> (pressedLastUpdate) that stores the state of the button at the last call to pollController() - so that it can tell when the button state has changed.

If this isn't enough code for you to figure out whats going on, I can send you a copy of the relevant code from my input package...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline astruyk

Senior Newbie





« Reply #3 - Posted 2006-05-24 16:30:55 »

Is there a way I can block until I'm sure the initialization is finished? If not, how can I avoid calling the poll() method before the controller is finished initializing?
Offline astruyk

Senior Newbie





« Reply #4 - Posted 2006-05-24 19:37:47 »

Peering into the debugger - I can't see anything overtly wrong with the DIAbstractController's event_queue state, the head and tail both are 0, and the queue seems to be full of [component=null, value=0, nanos=0] values, and there doesn't appear to be null keys or values in the id_to_components hashmap.

After doing some debugger-sleuthing, it appears that the error originates at the
1  
2  
3  
public final DIComponent mapObject(DIDeviceObject object) {
      return (DIComponent)object_to_component.get(object);
   }

method in the IDirectInputDevice.java file - object_to_component does not contain the correct DIDeviceObject. This causes the call from to the line highlighted below (from  DIControllers.java) to return null:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
   public final static synchronized boolean getNextDeviceEvent(Event event, IDirectInputDevice device) throws IOException {
      if (!device.getNextEvent(di_event))
         return false;
      DIDeviceObject object = device.mapEvent(di_event);
      int event_value;
      if (object.isRelative()) {
         event_value = object.getRelativeEventValue(di_event.getData());
      } else {
         event_value = di_event.getData();
      }
      DIComponent component = device.mapObject(object); // <-----------------------------------------------------
      event.set(component, component.getDeviceObject().convertValue(event_value), di_event.getNanos());
      return true;
   }


And the the event.set() line causes the the nullPointerException.

This 'unknown' object is present in the IDirectInputDevice's variable ('object' in the above context) ArrayList 'objects', but not in the 'object_to_component' HashMap. This 'unknown' object - has a name String that identifies it as "Axis 6" - and oddly enough an 'id' field with a 'null' value in it.

I'll do some more sleuthing to see if I can dig up why the rogue "Axis 6" component is being created in the first place - or why its not present in the object_to_component hashmap. I'm guessing that there's some obscure error going on with the actual gamepad hardware - something that's causing the actual jInput Component to fail to be created (so it can't be added to the object_to_component HashMap), but that allows it to get far enough to make it into the 'objects' list of the Controller. ... I'll try looking for the place where the object_to_component var is populated, might provide some insight.........
Offline astruyk

Senior Newbie





« Reply #5 - Posted 2006-05-24 19:41:51 »

Perhaps you can think of a case where an 'object' could be created, but not successfully mapped to a Component?
Offline endolf

JGO Coder


Medals: 7
Exp: 15 years


Current project release date: sometime in 3003


« Reply #6 - Posted 2006-05-24 20:16:31 »

Hi

Right, the object will not get registered if the component identifier can't be looked up. I suspect that the switch statement in IDirectInputDevice.getIdentifier is hitting the default part and returning null.

Can I suggest you stick a debug statment in there and dump out the value of guid_type, type and instance.

HTH

Endolf

Offline astruyk

Senior Newbie





« Reply #7 - Posted 2006-05-24 22:36:10 »

Here ya go. you were right that its returning null from that method - here's the info you asked for:

guid_type = 11
type = 2
instance  = 6

Offline endolf

JGO Coder


Medals: 7
Exp: 15 years


Current project release date: sometime in 3003


« Reply #8 - Posted 2006-05-25 12:41:52 »

Hi

This guid_type is 'unknown' type, so I've made it so that on that fiven guid_type it returns Component.Identifier.Axis.UNKOWN which is also new. I've only got linux to compile on atm (I'm at work), so I can't test it, but I have commited the change to CVS. If you could checkout the source and compile it, and test it, that would be very helpful.

Cheers

Endolf

Offline astruyk

Senior Newbie





« Reply #9 - Posted 2006-06-05 13:58:49 »

I'll give it a shot as soon as I can. Sorry for the delay - got busy there for a while Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (50 views)
2014-10-17 03:59:02

Norakomi (39 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (36 views)
2014-10-15 16:18:58

TehJavaDev (66 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!