Skip to content
Permalink
Browse files

BUGFIX: in version 1.0.6, if you start a game, then rotate the screen,

you immediately get a crash.

Major overhauls of thread management to combat memory leaks
  • Loading branch information...
jason.priebe@gmail.com
jason.priebe@gmail.com committed Mar 3, 2012
1 parent 9468b46 commit ee88cafbf525006f656dda4a46c5a3299740b7c0
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.smorgasbork.hotdeath"
android:versionCode="7"
android:versionName="1.0.6"
android:versionCode="8"
android:versionName="1.0.7"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.VIBRATE" />
@@ -9,6 +9,8 @@
public class Game extends Thread {
public static final int MAX_NUM_CARDS = 216;

private boolean m_stopping = false;

public static final int SEAT_SOUTH = 1;
public static final int SEAT_WEST = 2;
public static final int SEAT_NORTH = 3;
@@ -55,6 +57,11 @@

private JSONObject m_snapshot = null;

public boolean getStopping ()
{
return m_stopping;
}

public void setFastForward (boolean ff)
{
Log.d("HDU", "setFastForward ("
@@ -168,6 +175,27 @@ private void waitUntilUnpaused ()

public void shutdown ()
{
if (!m_stopping)
{
// on the first call, we'll set a flag
m_stopping = true;
Log.d("HDU", "Game thread shutdown requested...");
return;
}

// on the second call, we'll really shut down; but also be careful
// in case we get called more than two times...
Log.d("HDU", "Game thread nulling out references and exiting...");
if (m_gt != null)
{
m_gt.shutdown ();
m_go.shutdown ();

for (int i = 0; i < m_players.length; i++)
{
m_players[i].shutdown();
}
}
m_go = null;
m_ga = null;
m_gt = null;
@@ -427,13 +455,22 @@ public void dealHands()
if (android.os.Debug.isDebuggerConnected() && debugDeal)
{
int[][] hands = {
/* All four bastard cards...
/*
// try to get draw 4s stacked with hotdeath on top, and a magic 5 to null it
{Card.ID_RED_5_MAGIC, Card.ID_WILD_DRAWFOUR},
{Card.ID_BLUE_0, Card.ID_BLUE_1, Card.ID_BLUE_2, Card.ID_WILD_DB},
{Card.ID_RED_3, Card.ID_RED_4, Card.ID_RED_5, Card.ID_WILD_DRAWFOUR},
{Card.ID_GREEN_6, Card.ID_GREEN_7, Card.ID_GREEN_8, Card.ID_WILD_HD}
*/

/*
// All four bastard cards...
{Card.ID_BLUE_0_FUCKYOU, Card.ID_GREEN_0_QUITTER, Card.ID_YELLOW_0_SHITTER, Card.ID_RED_0_HD, Card.ID_BLUE_1, Card.ID_BLUE_2, Card.ID_BLUE_3},
{Card.ID_GREEN_1, Card.ID_GREEN_2, Card.ID_GREEN_3, Card.ID_GREEN_4, Card.ID_GREEN_5, Card.ID_GREEN_6, Card.ID_GREEN_7},
{Card.ID_RED_1, Card.ID_RED_2, Card.ID_RED_3, Card.ID_RED_4, Card.ID_RED_5, Card.ID_RED_6, Card.ID_RED_7},
{Card.ID_YELLOW_1, Card.ID_YELLOW_2, Card.ID_YELLOW_3, Card.ID_YELLOW_4, Card.ID_YELLOW_5, Card.ID_YELLOW_6, Card.ID_YELLOW_7}
*/

*/
/*
// this makes a mystery on a 69 highly likely
{Card.ID_YELLOW_6, Card.ID_WILD_MYSTERY, Card.ID_YELLOW_0_SHITTER},
@@ -482,11 +519,13 @@ public void dealHands()
{Card.ID_GREEN_3_AIDS, Card.ID_BLUE_2_SHIELD, Card.ID_GREEN_4_IRISH}
*/

/*
// want a retaliation thrown on a delayed blast
{Card.ID_BLUE_0_FUCKYOU, Card.ID_BLUE_1, Card.ID_BLUE_2, Card.ID_BLUE_3},
{Card.ID_RED_1, Card.ID_RED_2, Card.ID_RED_3, Card.ID_RED_3},
{Card.ID_GREEN_1, Card.ID_GREEN_2, Card.ID_WILD_DB},
{Card.ID_YELLOW_1, Card.ID_YELLOW_2, Card.ID_YELLOW_3}
*/
};

for (i = 0; i < 4; i++)
@@ -583,8 +622,6 @@ public void dealHands()
Hand h = (m_players[i]).getHand();
sortHand(h);
}

postDealHands();
}


@@ -691,16 +728,23 @@ public void startRound()
if (m_go.getStandardRules())
{
m_numCardsToDeal = 7;
dealHands();
}

m_numCardsToDeal = m_dealer.getNumCardsToDeal();
else
{
m_numCardsToDeal = m_dealer.getNumCardsToDeal();

if (m_stopping)
{
return;
}
}

dealHands();
postDealHands();
}

private void postDealHands ()
{

do
{
// FIXME!!! the dealer is supposed to eat penalties...
@@ -727,25 +771,35 @@ private void postDealHands ()
redrawTable ();
gotAllBastardCards (m_players[i]);
finishRound(m_players[i]);

return;
}
}


mainLoop ();
}

private void mainLoop ()
private void runRound ()
{
while (true)
{
m_snapshot = this.toJSON();
waitUntilUnpaused ();

if (m_roundComplete)
{
// this could conceivably happen if the round ends immediately after the deal
return;
}

if (m_stopping)
{
return;
}

if (advanceRound() == false)
{
break;
}
}
}
}

public void run ()
@@ -756,16 +810,35 @@ public void run ()
if (m_roundComplete)
{
waitForNextRound ();
}
else
{
mainLoop ();
startRound ();
}
}
else
{
startGame ();
}

while (!m_gameOver)
{
runRound ();
if (m_stopping)
{
shutdown ();
Log.d("HDU", "exiting Game.run()...");
return;
}
if (!m_gameOver)
{
waitForNextRound();
startRound ();
}
}

// call shutdown() once; when user backs out of the activity, shutdown() will
// get called for the second time, releasing all big references
shutdown();

Log.d("HDU", "exiting Game.run()...");
}

public void startGame()
@@ -829,6 +902,11 @@ public boolean advanceRound()
}

m_currPlayer.startTurn();

if (m_stopping)
{
return false;
}

if ((m_currPlayer.getHand()).hasValidCards(this)
&& !(m_currPlayer.getWantsToPass()))
@@ -854,13 +932,23 @@ public boolean advanceRound()
if (m_currColor == Card.COLOR_WILD)
{
m_currColor = m_currPlayer.chooseColor();

if (m_stopping)
{
return false;
}

String msg = String.format(getString (R.string.msg_color_chosen), seatToString(m_currPlayer.getSeat()), colorToString(m_currColor));
redrawTable ();
Log.d("HDU", msg);
//PromptUser(msg);
}

handleSpecialCards();
if (m_stopping)
{
return false;
}

// if previous player set us up, and we did not throw something
// that would negate the penalty, then we get penalized now
@@ -1175,12 +1263,6 @@ public void finishRound(Player p)
redrawTable();
}

else
{
msg = getString(R.string.msg_tap_draw_pile);
promptUser(msg);
waitForNextRound ();
}
}

public boolean roundIsActive ()
@@ -1199,6 +1281,9 @@ public boolean roundIsActive ()

private void waitForNextRound ()
{
String msg = getString(R.string.msg_tap_draw_pile);
promptUser(msg);

m_waitingToStartRound = true;
while (m_waitingToStartRound)
{
@@ -1211,8 +1296,6 @@ private void waitForNextRound ()

}
}

startRound();
}

public void drawPileTapped ()
@@ -1816,6 +1899,10 @@ else if (prevVal > 0 && prevVal < 10)
if (currID == Card.ID_RED_2_GLASNOST)
{
m_currPlayer.chooseVictim();
if (m_stopping)
{
return;
}
int victim = m_currPlayer.getChosenVictim();
// we'll set the victim after prompting the user for it
m_penalty.setFaceup(m_currCard, m_currPlayer, m_players[victim - 1]);
@@ -1872,6 +1959,10 @@ else if (prevVal > 0 && prevVal < 10)
if (getActivePlayerCount() > 3)
{
m_currPlayer.chooseVictim();
if (m_stopping)
{
return;
}
int victim = m_currPlayer.getChosenVictim();

// we'll set the victim after prompting the user for it
@@ -170,12 +170,8 @@ public void onConfigurationChanged(Configuration newConfig) {
protected void onDestroy() {
m_game.shutdown ();
m_game = null;

m_gt.shutdown ();
m_gt = null;

m_go.shutdown ();
m_go = null;
m_go = null;

super.onDestroy ();
};
@@ -334,15 +334,15 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh)
if (m_waitingToStartGame)
{
m_waitingToStartGame = false;
m_game.start();
m_game.start ();
}
}

public void startGameWhenReady ()
{
if (m_readyToStartGame)
{
m_game.start();
m_game.start ();
return;
}

@@ -80,6 +80,10 @@ public void startTurn()
{

}
if (m_game.getStopping())
{
return;
}
}

return;
@@ -101,6 +105,10 @@ public int getNumCardsToDeal ()
{

}
if (m_game.getStopping())
{
return 0;
}
}

return m_numCardsToDeal;
@@ -129,6 +137,10 @@ public int chooseColor()
{

}
if (m_game.getStopping())
{
return 0;
}
}

return m_chosenColor;
@@ -185,6 +197,10 @@ public void chooseVictim()
{

}
if (m_game.getStopping())
{
return;
}
}
}

0 comments on commit ee88caf

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