From f9afcc0e6fb395061b2e3eeb376b962abdcd76ce Mon Sep 17 00:00:00 2001 From: Andy2 Date: Fri, 30 Jul 2010 06:43:56 -0700 Subject: [PATCH 01/16] add ability to tag events as UI or not. CMD_DO is not. Only UI events in queue prevent engine from continuing. This fixes bug where server running engine on behalf of robot would starve the UI thread by looping forever seeing the engine bail because a CMD_DO was in the queue and then adding a CMD_DO to try running the engine yet again. --- .../eehouse/android/xw4/BoardActivity.java | 2 +- .../eehouse/android/xw4/jni/JNIThread.java | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java index 99abc2ff2..eadca9ba6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -592,7 +592,7 @@ public class BoardActivity extends Activity implements UtilCtxt { m_handler.post( new Runnable() { public void run() { if ( null != m_jniThread ) { - m_jniThread.handle( JNIThread.JNICmd.CMD_DO ); + m_jniThread.handle( JNIThread.JNICmd.CMD_DO, false ); } } } ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java index 9eaf3a5e3..e1862b294 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java @@ -25,6 +25,7 @@ import org.eehouse.android.xw4.Utils; import android.content.Context; import java.lang.InterruptedException; import java.util.concurrent.LinkedBlockingQueue; +import java.util.Iterator; import android.os.Handler; import android.os.Message; import android.graphics.Paint; @@ -99,10 +100,11 @@ public class JNIThread extends Thread { LinkedBlockingQueue m_queue; private class QueueElem { - protected QueueElem( JNICmd cmd, Object[] args ) + protected QueueElem( JNICmd cmd, boolean isUI, Object[] args ) { - m_cmd = cmd; m_args = args; + m_cmd = cmd; m_isUIEvent = isUI; m_args = args; } + boolean m_isUIEvent; JNICmd m_cmd; Object[] m_args; } @@ -132,8 +134,15 @@ public class JNIThread extends Thread { public boolean busy() { // synchronize this!!! - int siz = m_queue.size(); - return siz > 0; + boolean result = false; + Iterator iter = m_queue.iterator(); + while ( iter.hasNext() ) { + if ( iter.next().m_isUIEvent ) { + result = true; + break; + } + } + return result; } public void setInBackground( boolean inBack ) @@ -488,11 +497,16 @@ public class JNIThread extends Thread { Utils.logf( "run exiting" ); } // run - public void handle( JNICmd cmd, Object... args ) + public void handle( JNICmd cmd, boolean isUI, Object... args ) { - QueueElem elem = new QueueElem( cmd, args ); + QueueElem elem = new QueueElem( cmd, isUI, args ); // Utils.logf( "adding: " + cmd.toString() ); m_queue.add( elem ); } + public void handle( JNICmd cmd, Object... args ) + { + handle( cmd, true, args ); + } + } From b4f7a6917f32ea291e3e4dd8cee069bb16e29811 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Fri, 30 Jul 2010 07:16:24 -0700 Subject: [PATCH 02/16] wrap time in brackets for readability --- xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java index e39819642..e6acb2b58 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java @@ -54,7 +54,7 @@ public class Utils { public static void logf( String msg ) { s_time.setToNow(); - String time = s_time.format("%H:%M:%S"); + String time = s_time.format("[%H:%M:%S]"); long id = Thread.currentThread().getId(); Log.d( TAG, time + "-" + id + "-" + msg ); } // logf From d07d90761f5a63deff864562e33f9b9f4278bc5a Mon Sep 17 00:00:00 2001 From: Andy2 Date: Fri, 30 Jul 2010 17:38:07 -0700 Subject: [PATCH 03/16] remove logging --- xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java index a74bbc825..e9a3e2a1f 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -115,7 +115,6 @@ public class DBUtils { if ( null != summary.conType ) { values.put( DBHelper.CONTYPE, summary.conType.ordinal() ); - Utils.logf( "wrote CONTYPE" ); values.put( DBHelper.ROOMNAME, summary.roomName ); values.put( DBHelper.SMSPHONE, summary.smsPhone ); } From 13596f85387fe0bf30327e1f127ea38ac0b130bb Mon Sep 17 00:00:00 2001 From: Andy2 Date: Fri, 30 Jul 2010 17:40:46 -0700 Subject: [PATCH 04/16] synchronize read and write of files, fixing a race condition between BoardActivity shutdown (save) and GamesList refresh (open) that resulted in zero-length byte array being passed into the jni. It's now possible for the list to win the race and display old data, so a better solution would be to check-out the file in such a way that the list couldn't read it until it was update, but at least now we won't crash. --- .../eehouse/android/xw4/GameListAdapter.java | 22 ++-------------- .../org/eehouse/android/xw4/GameUtils.java | 25 ++++++++++++------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java index c690bd704..1f2c12bdd 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java @@ -62,13 +62,13 @@ public class GameListAdapter extends XWListAdapter { public Object getItem( int position ) { - String path = GameUtils.gamesList(m_context)[position]; + final String path = GameUtils.gamesList(m_context)[position]; View layout = m_viewsCache.get( path ); if ( null == layout ) { Utils.logf( "creating new list elem for %s", path ); layout = m_factory.inflate( m_layoutId, null ); - byte[] stream = open( path ); + byte[] stream = GameUtils.savedGame( m_context, path ); if ( null != stream ) { CurGameInfo gi = new CurGameInfo( m_context ); XwJNI.gi_from_stream( gi, stream ); @@ -103,24 +103,6 @@ public class GameListAdapter extends XWListAdapter { return (View)getItem( position ); } - private byte[] open( String file ) - { - byte[] stream = null; - try { - FileInputStream in = m_context.openFileInput( file ); - int len = in.available(); - stream = new byte[len]; - in.read( stream, 0, len ); - in.close(); - } catch ( java.io.FileNotFoundException ex ) { - Utils.logf( "got FileNotFoundException: " + ex.toString() ); - } catch ( java.io.IOException ex ) { - Utils.logf( "got IOException: " + ex.toString() ); - } - return stream; - } - - public void inval( String key ) { m_viewsCache.remove( key ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java index a80117777..8805878a7 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java @@ -31,15 +31,19 @@ import org.eehouse.android.xw4.jni.*; public class GameUtils { + private static Object s_syncObj = new Object(); + public static byte[] savedGame( Context context, String path ) { byte[] stream = null; try { - FileInputStream in = context.openFileInput( path ); - int len = in.available(); - stream = new byte[len]; - in.read( stream, 0, len ); - in.close(); + synchronized( s_syncObj ) { + FileInputStream in = context.openFileInput( path ); + int len = in.available(); + stream = new byte[len]; + in.read( stream, 0, len ); + in.close(); + } } catch ( java.io.FileNotFoundException fnf ) { Utils.logf( fnf.toString() ); stream = null; @@ -109,6 +113,7 @@ public class GameUtils { public static void deleteGame( Context context, String path ) { + // does this need to be synchronized? context.deleteFile( path ); DBUtils.saveSummary( path, null ); } @@ -147,10 +152,12 @@ public class GameUtils { public static void saveGame( Context context, byte[] bytes, String path ) { try { - FileOutputStream out = context.openFileOutput( path, - Context.MODE_PRIVATE ); - out.write( bytes ); - out.close(); + synchronized( s_syncObj ) { + FileOutputStream out = + context.openFileOutput( path, Context.MODE_PRIVATE ); + out.write( bytes ); + out.close(); + } } catch ( java.io.IOException ex ) { Utils.logf( "got IOException: " + ex.toString() ); } From 205723e03bbbde6c2bfdf91c46168f17ab6f24a2 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Fri, 30 Jul 2010 17:44:20 -0700 Subject: [PATCH 05/16] add missing event to logging --- xwords4/common/comms.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 1f9f46452..58bd7e587 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -1070,13 +1070,17 @@ relayCmdToStr( XWRELAY_Cmd cmd ) CASESTR( XWRELAY_CONNECT_RESP ); CASESTR( XWRELAY_RECONNECT_RESP ); CASESTR( XWRELAY_ALLHERE ); + CASESTR( XWRELAY_ALLBACK ); CASESTR( XWRELAY_DISCONNECT_YOU ); CASESTR( XWRELAY_DISCONNECT_OTHER ); CASESTR( XWRELAY_CONNECTDENIED ); CASESTR( XWRELAY_HEARTBEAT ); CASESTR( XWRELAY_MSG_FROMRELAY ); CASESTR( XWRELAY_MSG_TORELAY ); - default: return ""; + default: + XP_LOGF( "%s: unknown cmd: %d", __func__, cmd ); + XP_ASSERT( 0 ); + return ""; } } # endif From 269bd15a45c5a9ddb883869c54afe316fa76cb5c Mon Sep 17 00:00:00 2001 From: Andy2 Date: Tue, 10 Aug 2010 06:12:09 -0700 Subject: [PATCH 06/16] change constants for beta 14 --- xwords4/android/XWords4/AndroidManifest.xml | 4 ++-- .../XWords4/src/org/eehouse/android/xw4/XWConstants.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xwords4/android/XWords4/AndroidManifest.xml b/xwords4/android/XWords4/AndroidManifest.xml index 002486e41..2036b7375 100644 --- a/xwords4/android/XWords4/AndroidManifest.xml +++ b/xwords4/android/XWords4/AndroidManifest.xml @@ -21,8 +21,8 @@ to come from a domain that you own or have control over. --> diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java index 6417ecb2c..f49d53fc9 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java @@ -23,5 +23,5 @@ package org.eehouse.android.xw4; public interface XWConstants { public static final String GAME_EXTN = ".xwg"; public static final String DICT_EXTN = ".xwd"; - public static final String VERSION_STR = "4.4 beta 13"; + public static final String VERSION_STR = "4.4 beta 14"; } From 287ab2485f88ac66f9612c6c0661a537b06e6705 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Tue, 10 Aug 2010 18:48:19 -0700 Subject: [PATCH 07/16] add changes summary dialog shown on first launch after an upgrade. --- xwords4/android/XWords4/res/raw/changes | 32 +++++ .../android/XWords4/res/values/strings.xml | 1 + .../eehouse/android/xw4/FirstRunDialog.java | 116 ++++++++++++++++++ .../org/eehouse/android/xw4/GamesList.java | 2 + 4 files changed, 151 insertions(+) create mode 100644 xwords4/android/XWords4/res/raw/changes create mode 100644 xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java diff --git a/xwords4/android/XWords4/res/raw/changes b/xwords4/android/XWords4/res/raw/changes new file mode 100644 index 000000000..c9df628a4 --- /dev/null +++ b/xwords4/android/XWords4/res/raw/changes @@ -0,0 +1,32 @@ + + + + + + +Crosswords 4.4 beta 14 release + +
    New features: +
  • This spiffy per-release dialog
  • +
+ +
    Bugs fixed: +
  • bug 1
  • +
  • bug 2
  • +
+ +
    Coming soon +
  • builtin online help
  • +
  • rewrite of gameplay via relay to make connecting easier etc.
  • +
+ +

Please remember that this is beta software. Letting me know (at +eehouse@eehouse.org) what's broken and what features you'd most like +to see is the best way to help get this to release quality +quickly.

+ +

Thanks!
--Eric

+ + diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml index a88b942fb..3e5f34c4c 100644 --- a/xwords4/android/XWords4/res/values/strings.xml +++ b/xwords4/android/XWords4/res/values/strings.xml @@ -361,5 +361,6 @@ Timer minutes per player Source version id + Recent changes diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java new file mode 100644 index 000000000..962dd6313 --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java @@ -0,0 +1,116 @@ +/* -*- compile-command: "cd ../../../../../; ant install"; -*- */ +/* + * Copyright 2010 by Eric House (xwords@eehouse.org). All rights + * reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package org.eehouse.android.xw4; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.pm.PackageInfo; +import android.app.AlertDialog; +import android.webkit.WebView; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/* Put up a dialog greeting user after every upgrade. Based on + * similar feature in OpenSudoku, to whose author "Thanks". + */ + +public class FirstRunDialog { + private static final String HIDDEN_PREFS = "xwprefs_hidden"; + private static final String SHOWN_VERSION_KEY = "SHOWN_VERSION_KEY"; + + static void show( Context context ) + { + int thisVersion = 0; + try { + thisVersion = context.getPackageManager() + .getPackageInfo(context.getPackageName(), 0) + .versionCode; + Utils.logf( "versionCode: %d", thisVersion ); + } catch ( Exception e ) { + } + + if ( thisVersion > 0 ) { + SharedPreferences prefs = + context.getSharedPreferences( HIDDEN_PREFS, + Context.MODE_PRIVATE ); + int shownVersion = prefs.getInt( SHOWN_VERSION_KEY, 0 ); + if ( shownVersion < thisVersion ) { + showDialog( context ); + + Editor editor = prefs.edit(); + editor.putInt( SHOWN_VERSION_KEY, thisVersion ); + editor.commit(); + } + } + } + + private static void showDialog( Context context ) + { + String page = null; + InputStream inputStream = null; + try { + inputStream = context.getResources() + .openRawResource(R.raw.changes); + + final char[] buf = new char[0x1000]; + StringBuilder stringBuilder = new StringBuilder(); + Reader reader = new InputStreamReader( inputStream, "UTF-8" ); + int nRead; + do { + nRead = reader.read( buf, 0, buf.length ); + if ( nRead > 0 ) { + stringBuilder.append( buf, 0, nRead ); + } + } while ( nRead >= 0 ); + + page = stringBuilder.toString(); + } + catch ( IOException ioe ) { + Utils.logf( ioe.toString() ); + } + finally { + // could just catch NPE.... + if ( null != inputStream ) { + try { + inputStream.close(); + } catch ( IOException ioe ) { + Utils.logf( ioe.toString() ); + } + } + } + + // This won't support e.g mailto refs. Probably want to + // launch the browser with an intent eventually. + WebView view = new WebView( context ); + view.loadData( page, "text/html", "utf-8" ); + + AlertDialog dialog = new AlertDialog.Builder( context ) + .setIcon(android.R.drawable.ic_menu_info_details) + .setTitle( R.string.changes_title ) + .setView( view ) + .setPositiveButton( R.string.button_ok, null) + .create(); + dialog.show(); + } +} diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java index de30d2ad7..99cfe7d4c 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -127,6 +127,8 @@ public class GamesList extends ListActivity { m_adapter = new GameListAdapter( this ); setListAdapter( m_adapter ); + + FirstRunDialog.show( this ); } @Override From e720fe79ab3ec8e579ada90393dbbf121128227e Mon Sep 17 00:00:00 2001 From: Andy2 Date: Tue, 10 Aug 2010 20:32:04 -0700 Subject: [PATCH 08/16] wrap in ScrollView so can scroll --- .../android/XWords4/res/layout/about_dlg.xml | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/xwords4/android/XWords4/res/layout/about_dlg.xml b/xwords4/android/XWords4/res/layout/about_dlg.xml index 623ef8908..6c53fd279 100644 --- a/xwords4/android/XWords4/res/layout/about_dlg.xml +++ b/xwords4/android/XWords4/res/layout/about_dlg.xml @@ -1,29 +1,36 @@ - - + - + - + - + - + - + + + + + + From fc603645d1964cbf22d57c9d1d2ed50f71ab4296 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Tue, 10 Aug 2010 20:33:33 -0700 Subject: [PATCH 09/16] make changes dialog launchable from About dialog (so reachable other than immediately after upgrade) --- .../android/XWords4/res/values/strings.xml | 1 + .../eehouse/android/xw4/FirstRunDialog.java | 33 +++++++++++-------- .../org/eehouse/android/xw4/GamesList.java | 2 +- .../src/org/eehouse/android/xw4/Utils.java | 12 ++++++- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml index 3e5f34c4c..90c95d620 100644 --- a/xwords4/android/XWords4/res/values/strings.xml +++ b/xwords4/android/XWords4/res/values/strings.xml @@ -362,5 +362,6 @@ Source version id Recent changes + Recent changes diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java index 962dd6313..4f172dea6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/FirstRunDialog.java @@ -39,25 +39,32 @@ public class FirstRunDialog { private static final String HIDDEN_PREFS = "xwprefs_hidden"; private static final String SHOWN_VERSION_KEY = "SHOWN_VERSION_KEY"; - static void show( Context context ) + static void show( Context context, boolean skipCheck ) { int thisVersion = 0; - try { - thisVersion = context.getPackageManager() - .getPackageInfo(context.getPackageName(), 0) - .versionCode; - Utils.logf( "versionCode: %d", thisVersion ); - } catch ( Exception e ) { + int shownVersion = 0; + + if ( !skipCheck ) { + try { + thisVersion = context.getPackageManager() + .getPackageInfo(context.getPackageName(), 0) + .versionCode; + Utils.logf( "versionCode: %d", thisVersion ); + } catch ( Exception e ) { + } } + SharedPreferences prefs = null; if ( thisVersion > 0 ) { - SharedPreferences prefs = - context.getSharedPreferences( HIDDEN_PREFS, - Context.MODE_PRIVATE ); - int shownVersion = prefs.getInt( SHOWN_VERSION_KEY, 0 ); - if ( shownVersion < thisVersion ) { - showDialog( context ); + prefs = context.getSharedPreferences( HIDDEN_PREFS, + Context.MODE_PRIVATE ); + shownVersion = prefs.getInt( SHOWN_VERSION_KEY, 0 ); + } + if ( skipCheck || shownVersion < thisVersion ) { + showDialog( context ); + + if ( !skipCheck ) { Editor editor = prefs.edit(); editor.putInt( SHOWN_VERSION_KEY, thisVersion ); editor.commit(); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java index 99cfe7d4c..a48cc00d1 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -128,7 +128,7 @@ public class GamesList extends ListActivity { m_adapter = new GameListAdapter( this ); setListAdapter( m_adapter ); - FirstRunDialog.show( this ); + FirstRunDialog.show( this, false ); } @Override diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java index e6acb2b58..66bccf908 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java @@ -25,6 +25,7 @@ import java.lang.Thread; import android.widget.Toast; import android.content.Context; import android.content.Intent; +import android.content.DialogInterface; import android.widget.CheckBox; import android.app.Activity; import android.app.Dialog; @@ -71,7 +72,7 @@ public class Utils { Toast.makeText( context, text, Toast.LENGTH_SHORT).show(); } - static Dialog onCreateDialog( Context context, int id ) + static Dialog onCreateDialog( final Context context, int id ) { Assert.assertTrue( DIALOG_ABOUT == id ); LayoutInflater factory = LayoutInflater.from( context ); @@ -93,6 +94,15 @@ public class Utils { .setIcon( R.drawable.icon48x48 ) .setTitle( R.string.app_name ) .setView( view ) + .setPositiveButton( R.string.changes_button, + new DialogInterface.OnClickListener() { + @Override + public void onClick( DialogInterface dlg, + int which ) + { + FirstRunDialog.show( context, true ); + } + } ) .create(); } From 81ad7719b1719f4d9cffddfb57d6c65c1db351a8 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Tue, 10 Aug 2010 21:34:44 -0700 Subject: [PATCH 10/16] list changes since b13 --- xwords4/android/XWords4/res/raw/changes | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/xwords4/android/XWords4/res/raw/changes b/xwords4/android/XWords4/res/raw/changes index c9df628a4..b7ec04e15 100644 --- a/xwords4/android/XWords4/res/raw/changes +++ b/xwords4/android/XWords4/res/raw/changes @@ -13,13 +13,14 @@
    Bugs fixed: -
  • bug 1
  • -
  • bug 2
  • +
  • Crash exiting board view
  • +
  • Hang searching for robot move
  • +
  • Crash putting up progress dialog after board hidden
-
    Coming soon -
  • builtin online help
  • -
  • rewrite of gameplay via relay to make connecting easier etc.
  • +
      Coming soon: +
    • builtin hints and help
    • +
    • rewrite of gameplay via relay to make connecting easier and allow closed game to receive moves.

    Please remember that this is beta software. Letting me know (at From 09bc83429e45ec77def81d14bdb73d41bcae0766 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Wed, 11 Aug 2010 18:50:16 -0700 Subject: [PATCH 11/16] add and set new flags for crosshairs so platforms can do better than fill cells as is done for focus. --- xwords4/common/boarddrw.c | 29 +++++++++++++++++++++-------- xwords4/common/dragdrpp.c | 16 +++++++++------- xwords4/common/dragdrpp.h | 4 +++- xwords4/common/draw.h | 4 +++- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/xwords4/common/boarddrw.c b/xwords4/common/boarddrw.c index 0a9480adf..aa0873044 100644 --- a/xwords4/common/boarddrw.c +++ b/xwords4/common/boarddrw.c @@ -231,6 +231,23 @@ makeMiniWindowForTrade( BoardCtxt* board ) makeMiniWindowForText( board, text, MINIWINDOW_TRADING ); } /* makeMiniWindowForTrade */ +#ifdef XWFEATURE_CROSSHAIRS +static CellFlags +flagsForCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row ) +{ + CellFlags flags = 0; + XP_Bool inHor, inVert; + dragDropInCrosshairs( board, col, row, &inHor, &inVert ); + if ( inHor ) { + flags |= CELL_CROSSHOR; + } + if ( inVert ) { + flags |= CELL_CROSSVERT; + } + return flags; +} +#endif + static void drawBoard( BoardCtxt* board ) { @@ -310,16 +327,14 @@ drawBoard( BoardCtxt* board ) CellFlags flags = CELL_NONE; bonus = util_getSquareBonus( board->util, model, col, row ); hintAtts = figureHintAtts( board, col, row ); - if ( 0 ) { #ifdef KEYBOARD_NAV - } else if ( cellFocused( board, col, row ) ) { + if ( cellFocused( board, col, row ) ) { flags |= CELL_ISCURSOR; + } #endif #ifdef XWFEATURE_CROSSHAIRS - } else if ( dragDropInCrosshairs( board, col, row ) ) { - flags |= CELL_ISCURSOR; + flags |= flagsForCrosshairs( board, col, row ); #endif - } draw_drawBoardArrow( board->draw, &arrowRect, bonus, arrow->vert, hintAtts, flags ); @@ -433,9 +448,7 @@ drawCell( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Bool skipBlanks ) } #endif #ifdef XWFEATURE_CROSSHAIRS - if ( dragDropInCrosshairs( board, col, row ) ) { - flags |= CELL_ISCURSOR; - } + flags |= flagsForCrosshairs( board, col, row ); #endif success = draw_drawCell( board->draw, &cellRect, textP, bptr, diff --git a/xwords4/common/dragdrpp.c b/xwords4/common/dragdrpp.c index 92a39686b..7bdad2e73 100644 --- a/xwords4/common/dragdrpp.c +++ b/xwords4/common/dragdrpp.c @@ -659,16 +659,18 @@ startScrollTimerIf( BoardCtxt* board ) } /* startScrollTimerIf */ #ifdef XWFEATURE_CROSSHAIRS -XP_Bool -dragDropInCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row ) +void +dragDropInCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row, + XP_Bool* inHor, XP_Bool* inVert ) { - XP_Bool result = dragDropInProgress( board ); - if ( result ) { + + if ( dragDropInProgress( board ) ) { const DragState* ds = &board->dragState; - result = ds->crosshairs.col == col - || ds->crosshairs.row == row; + *inHor = ds->crosshairs.row == row; + *inVert = ds->crosshairs.col == col; + } else { + *inHor = *inVert = XP_FALSE; } - return result; } /* dragDropInCrosshairs */ static void diff --git a/xwords4/common/dragdrpp.h b/xwords4/common/dragdrpp.h index 73f3368c4..e93de9de0 100644 --- a/xwords4/common/dragdrpp.h +++ b/xwords4/common/dragdrpp.h @@ -58,7 +58,9 @@ XP_Bool dragDropGetHintLimits( const BoardCtxt* board, BdHintLimits* limits ); void dragDropTileInfo( const BoardCtxt* board, Tile* tile, XP_Bool* isBlank ); #ifdef XWFEATURE_CROSSHAIRS -XP_Bool dragDropInCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row ); +void dragDropInCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row, + XP_Bool* inHor, XP_Bool* inVert ); + #endif #ifdef CPLUS diff --git a/xwords4/common/draw.h b/xwords4/common/draw.h index cf2ade55d..10774614a 100644 --- a/xwords4/common/draw.h +++ b/xwords4/common/draw.h @@ -41,7 +41,9 @@ typedef enum { , CELL_VALHIDDEN = 0x20 /* show letter only, not value */ , CELL_DRAGSRC = 0x40 /* where drag originated */ , CELL_DRAGCUR = 0x80 /* where drag is now */ - , CELL_ALL = 0xFF + , CELL_CROSSVERT = 0x100 /* vertical component of crosshair */ + , CELL_CROSSHOR = 0x200 /* horizontal component of crosshair */ + , CELL_ALL = 0x3FF } CellFlags; typedef struct DrawScoreInfo { From 2d69d8f2b0f84cbc48ca20a19781eb6fa1593599 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Wed, 11 Aug 2010 18:51:09 -0700 Subject: [PATCH 12/16] use new crosshairs flags to draw a cross in the middle third of cells --- xwords4/linux/gtkdraw.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/xwords4/linux/gtkdraw.c b/xwords4/linux/gtkdraw.c index a236079ad..b8c34cfae 100644 --- a/xwords4/linux/gtkdraw.c +++ b/xwords4/linux/gtkdraw.c @@ -420,6 +420,28 @@ drawHintBorders( GtkDrawCtx* dctx, const XP_Rect* rect, HintAtts hintAtts) } } +#ifdef XWFEATURE_CROSSHAIRS +static void +drawCrosshairs( GtkDrawCtx* dctx, const XP_Rect* rect, CellFlags flags ) +{ + XP_Rect hairRect; + if ( 0 != (flags & CELL_CROSSHOR) ) { + hairRect = *rect; + hairRect.height /= 3; + hairRect.top += hairRect.height; + gtkFillRect( dctx, &hairRect, &dctx->cursor ); + } + if ( 0 != (flags & CELL_CROSSVERT) ) { + hairRect = *rect; + hairRect.width /= 3; + hairRect.left += hairRect.width; + gtkFillRect( dctx, &hairRect, &dctx->cursor ); + } +} +#else +# define drawCrosshairs( a, b, c ) +#endif + static XP_Bool gtk_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* letter, const XP_Bitmaps* bitmaps, Tile XP_UNUSED(tile), @@ -504,6 +526,7 @@ gtk_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* letter, } drawHintBorders( dctx, rect, hintAtts ); + drawCrosshairs( dctx, rect, flags ); return XP_TRUE; } /* gtk_draw_drawCell */ From d44b08b60985140928b7468cac3cd69313bba5fa Mon Sep 17 00:00:00 2001 From: Andy2 Date: Wed, 11 Aug 2010 18:51:33 -0700 Subject: [PATCH 13/16] remove unused and confusing duplicate flags. --- .../org/eehouse/android/xw4/jni/DrawScoreInfo.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawScoreInfo.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawScoreInfo.java index d5bdeeb7d..2c6f9a830 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawScoreInfo.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawScoreInfo.java @@ -20,20 +20,6 @@ package org.eehouse.android.xw4.jni; public class DrawScoreInfo { - - public static final int CELL_NONE = 0x00; - public static final int CELL_ISBLANK = 0x01; - public static final int CELL_HIGHLIGHT = 0x02; - public static final int CELL_ISSTAR = 0x04; - public static final int CELL_ISCURSOR = 0x08; - public static final int CELL_ISEMPTY = 0x10; /* of a tray tile slot */ - public static final int CELL_VALHIDDEN = 0x20; /* show letter only, not value */ - public static final int CELL_DRAGSRC = 0x40; /* where drag originated */ - public static final int CELL_DRAGCUR = 0x80; /* where drag is now */ - public static final int CELL_ALL = 0xFF; - - // LastScoreCallback lsc; - // void* lscClosure; public String name; public int playerNum; public int totalScore; From ac022ea5a58760e304c39333dd75ba9d000c6a18 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Wed, 11 Aug 2010 18:53:12 -0700 Subject: [PATCH 14/16] add java version of new crosshairs flags; draw crosshairs 1/3 width/height of cells instead of reusing focus code to color background. --- .../org/eehouse/android/xw4/BoardView.java | 21 +++++++++++++++++-- .../org/eehouse/android/xw4/jni/DrawCtx.java | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java index a088c1651..4c501e6e0 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java @@ -445,8 +445,8 @@ public class BoardView extends View implements DrawCtx, BoardHandler, } } - public boolean drawCell( Rect rect, String text, int tile, int owner, - int bonus, int hintAtts, int flags ) + public boolean drawCell( final Rect rect, String text, int tile, int owner, + int bonus, int hintAtts, final int flags ) { int backColor; boolean empty = 0 != (flags & (CELL_DRAGSRC|CELL_ISEMPTY)); @@ -500,6 +500,8 @@ public class BoardView extends View implements DrawCtx, BoardHandler, } // frame the cell m_canvas.drawRect( rect, m_strokePaint ); + + drawCrosshairs( rect, flags ); return true; } // drawCell @@ -779,6 +781,21 @@ public class BoardView extends View implements DrawCtx, BoardHandler, } } + private void drawCrosshairs( final Rect rect, final int flags ) + { + int color = m_otherColors[CommonPrefs.COLOR_FOCUS]; + if ( 0 != (flags & CELL_CROSSHOR) ) { + Rect hairRect = new Rect( rect ); + hairRect.inset( 0, hairRect.height() / 3 ); + fillRect( hairRect, color ); + } + if ( 0 != (flags & CELL_CROSSVERT) ) { + Rect hairRect = new Rect( rect ); + hairRect.inset( hairRect.width() / 3, 0 ); + fillRect( hairRect, color ); + } + } + private void fillRect( Rect rect, int color ) { m_fillPaint.setColor( color ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawCtx.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawCtx.java index 098479507..3ec984e5d 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawCtx.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/DrawCtx.java @@ -31,7 +31,9 @@ public interface DrawCtx { static final int CELL_VALHIDDEN = 0x20; /* show letter only, not value */ static final int CELL_DRAGSRC = 0x40; /* where drag originated */ static final int CELL_DRAGCUR = 0x80; /* where drag is now */ - static final int CELL_ALL = 0xFF; + static final int CELL_CROSSVERT = 0x100; + static final int CELL_CROSSHOR = 0x200; + static final int CELL_ALL = 0x3FF; /* BoardObjectType */ static final int OBJ_NONE = 0; From 38ed6e4054fc1252ded4a59b3c4df2942560a123 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Wed, 11 Aug 2010 21:10:10 -0700 Subject: [PATCH 15/16] add missing close tag --- xwords4/android/XWords4/res/raw/changes | 1 + 1 file changed, 1 insertion(+) diff --git a/xwords4/android/XWords4/res/raw/changes b/xwords4/android/XWords4/res/raw/changes index b7ec04e15..9791b965a 100644 --- a/xwords4/android/XWords4/res/raw/changes +++ b/xwords4/android/XWords4/res/raw/changes @@ -31,3 +31,4 @@ quickly.

    Thanks!
    --Eric

    + From 3dba8ba13b1f4c96aa8d99c8d4db463f12624cf3 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Tue, 24 Aug 2010 18:38:12 -0700 Subject: [PATCH 16/16] Fix bug reported by user: if robot finishes a search but fails to find a move it's still done with its turn and must trade or pass. --- xwords4/common/engine.c | 6 ++++-- xwords4/common/server.c | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/xwords4/common/engine.c b/xwords4/common/engine.c index 801ce393d..b9c6cf0ed 100644 --- a/xwords4/common/engine.c +++ b/xwords4/common/engine.c @@ -513,11 +513,13 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model, result = XP_FALSE; } else { PossibleMove* move; - result = chooseMove( engine, &move ); - if ( result ) { + if ( chooseMove( engine, &move ) ) { XP_ASSERT( !!newMove ); XP_MEMCPY( newMove, &move->moveInfo, sizeof(*newMove) ); + } else { + newMove->nTiles = 0; } + result = XP_TRUE; } util_engineStopping( engine->util ); diff --git a/xwords4/common/server.c b/xwords4/common/server.c index 70517fa3c..1f89f1ba3 100644 --- a/xwords4/common/server.c +++ b/xwords4/common/server.c @@ -642,7 +642,7 @@ static XP_Bool makeRobotMove( ServerCtxt* server ) { XP_Bool result = XP_FALSE; - XP_Bool finished; + XP_Bool searchComplete; XP_S16 turn; const TrayTileSet* tileSet; MoveInfo newMove; @@ -674,14 +674,14 @@ makeRobotMove( ServerCtxt* server ) } XP_ASSERT( !!server_getEngineFor( server, turn ) ); - finished = engine_findMove( server_getEngineFor( server, turn ), - model, model_getDictionary( model ), - tileSet->tiles, tileSet->nTiles, XP_FALSE, + searchComplete = engine_findMove( server_getEngineFor( server, turn ), + model, model_getDictionary( model ), + tileSet->tiles, tileSet->nTiles, XP_FALSE, #ifdef XWFEATURE_SEARCHLIMIT - NULL, XP_FALSE, + NULL, XP_FALSE, #endif - targetScore, &canMove, &newMove ); - if ( finished ) { + targetScore, &canMove, &newMove ); + if ( searchComplete ) { const XP_UCHAR* str; XWStreamCtxt* stream = NULL;