Skip to content
Permalink
Browse files

Merge pull request #539 from nicklauslittle/multiplayer-assignment-fi…

…x-issue-538

Fixes issues where some controllers have matching descriptors.
  • Loading branch information
fzurita committed Jan 10, 2016
2 parents 5a317b8 + 4dd7d29 commit 33036d5f674eb92f1ac2049471ef8bf04b33b20b
Showing with 83 additions and 29 deletions.
  1. +83 −29 src/paulscode/android/mupen64plusae/input/map/PlayerMap.java
@@ -20,7 +20,9 @@
*/
package paulscode.android.mupen64plusae.input.map;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;

import org.mupen64plusae.v3.alpha.R;
@@ -37,7 +39,7 @@
/** A map where the device unique name maps to an id.
* When the device reconnects and it is given a new id,
* this map allows the old id to be looked up so it can be replaced with the new id. */
private HashMap<String, Integer> deviceNameToId = new HashMap<String, Integer>();
private HashMap<String, Collection<Integer>> deviceNameToId = new HashMap<String, Collection<Integer>>();

public static boolean isDeviceId( String deviceName )
{
@@ -125,20 +127,27 @@ public boolean reconnectDevice( int hardwareId )
{
// ...and if the device was previously mapped to a player...
String uniqueName = AbstractProvider.getUniqueName( hardwareId );
Integer oldId = deviceNameToId.get( uniqueName );
Collection<Integer> ids = deviceNameToId.get( uniqueName );

if( oldId != null && !AbstractProvider.isHardwareAvailable( oldId ) )
if( ids != null )
{
int player = mMap.get( oldId );

if( player > 0 )
for( Integer oldId : ids )
{
// ...then replace the old id with the new one.
Log.v( "PlayerMap", "Reconnecting device " + oldId + " as " + hardwareId + " for player " + player );
mMap.delete( oldId );
mMap.append( hardwareId, player );
deviceNameToId.put( uniqueName, hardwareId );
return true;
if( oldId != null && !AbstractProvider.isHardwareAvailable( oldId ) )
{
int player = mMap.get( oldId );

if( player > 0 )
{
// ...then replace the old id with the new one.
Log.v( "PlayerMap", "Reconnecting device " + oldId + " as " + hardwareId + " for player " + player );
mMap.delete( oldId );
mMap.append( hardwareId, player );
ids.remove( oldId );
ids.add( hardwareId );
return true;
}
}
}
}
}
@@ -157,7 +166,17 @@ public void map( int hardwareId, int player )
{
unmap( hardwareId );
mMap.put( hardwareId, player );
deviceNameToId.put( AbstractProvider.getUniqueName( hardwareId ), hardwareId );

String name = AbstractProvider.getUniqueName( hardwareId );
Collection<Integer> ids = deviceNameToId.get( name );

if( ids == null )
{
ids = new HashSet<Integer>();
deviceNameToId.put( name, ids );
}

ids.add( hardwareId );
}
else
Log.w( "InputMap", "Invalid player specified in map(.,.): " + player );
@@ -167,12 +186,15 @@ public void unmap( int hardwareId )
{
mMap.delete( hardwareId );

for( Entry<String, Integer> entry : deviceNameToId.entrySet() )
for( Entry<String, Collection<Integer>> entry : deviceNameToId.entrySet() )
{
if( entry.getValue() == hardwareId )
for( Integer id : entry.getValue() )
{
deviceNameToId.remove( entry.getKey() );
break;
if( id == hardwareId )
{
entry.getValue().remove( hardwareId );
return;
}
}
}
}
@@ -217,17 +239,20 @@ public String serialize()
// Serialize the map data to a multi-delimited string
String result = "";

for( Entry<String, Integer> entry : deviceNameToId.entrySet() )
for( Entry<String, Collection<Integer>> entry : deviceNameToId.entrySet() )
{
// If the device name is the id, then store the latest id, otherwise the device's unique name
String device = ( isDeviceId( entry.getKey() ) ) ?
entry.getValue().toString() :
entry.getKey();
int player = mMap.get( entry.getValue() );

// Putting the value first makes the string a bit more human readable IMO
if( player > 0 && device != null )
result += player + ":" + device + ",";
for( Integer id : entry.getValue() )
{
// If the device name is the id, then store the latest id, otherwise the device's unique name
String device = ( isDeviceId( entry.getKey() ) ) ?
id.toString() :
( entry.getKey() + "#" + id.toString() );
int player = mMap.get( id );

// Putting the value first makes the string a bit more human readable IMO
if( player > 0 && device != null )
result += player + ":" + device + ",";
}
}

Log.v("PlayerMap", "Serializing: " + result);
@@ -261,8 +286,28 @@ public void deserialize( String s )
try
{
int player = Integer.parseInt( elements[0] );
String[] deviceProperties = elements[1].split("#");
String deviceName = elements[1];
int id = AbstractProvider.getHardwareId( elements[1] );
int id = 0;

// Try to parse the hardware id and determine if the same name
// is still at that id (some devices share the name and can
// only be distinguished from each other by id)
if( deviceProperties.length == 2 )
{
deviceName = deviceProperties[0];

try { id = Integer.parseInt( deviceProperties[1] ); }
catch( NumberFormatException ignored ) { }

// Check to make sure the device is valid
if( !deviceName.equals( AbstractProvider.getUniqueName( id ) ) )
id = AbstractProvider.getHardwareId( deviceName );
}

// Try to get the hardware id from the device name (for backwards compatibility)
else
id = AbstractProvider.getHardwareId( deviceName );

// If the specified device is not currently connected.
if( id == 0 )
@@ -280,7 +325,16 @@ public void deserialize( String s )
deviceName = AbstractProvider.getUniqueName( id );
}

deviceNameToId.put( deviceName , id );
// Add the device to the appropriate places in the lists
Collection<Integer> ids = deviceNameToId.get( deviceName );

if( ids == null )
{
ids = new HashSet<Integer>();
deviceNameToId.put( deviceName, ids );
}

ids.add( id );
mMap.put( id, player );
}
catch( NumberFormatException ignored )

0 comments on commit 33036d5

Please sign in to comment.
You can’t perform that action at this time.