opening saved games and saving of changes now work.

This commit is contained in:
Eric House 2013-01-05 21:01:26 -08:00
parent a8014a855b
commit b61ed7b631
6 changed files with 111 additions and 24 deletions

View file

@ -55,29 +55,37 @@ writeToDB( XWStreamCtxt* stream, void* closure )
{ {
int result; int result;
CommonGlobals* cGlobals = (CommonGlobals*)closure; CommonGlobals* cGlobals = (CommonGlobals*)closure;
sqlite3_int64 rowid = cGlobals->rowid; sqlite3_int64 selRow = cGlobals->selRow;
sqlite3* pDb = cGlobals->pDb; sqlite3* pDb = cGlobals->pDb;
XP_U16 len = stream_getSize( stream ); XP_U16 len = stream_getSize( stream );
char buf[256];
char* query;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
if ( 0 == rowid ) { /* new row; need to insert blob first */ if ( -1 == selRow ) { /* new row; need to insert blob first */
const char* txt = "INSERT INTO games (game) VALUES (?)"; query = "INSERT INTO games (game) VALUES (?)";
result = sqlite3_prepare_v2( pDb, txt, -1, &stmt, NULL ); } else {
XP_ASSERT( SQLITE_OK == result ); const char* fmt = "UPDATE games SET game=? where rowid=%lld";
result = sqlite3_bind_zeroblob( stmt, 1 /*col 0 ??*/, len ); snprintf( buf, sizeof(buf), fmt, selRow );
XP_ASSERT( SQLITE_OK == result ); query = buf;
result = sqlite3_step( stmt ); }
XP_ASSERT( SQLITE_DONE == result );
rowid = sqlite3_last_insert_rowid( pDb ); result = sqlite3_prepare_v2( pDb, query, -1, &stmt, NULL );
XP_LOGF( "%s: new rowid: %lld", __func__, rowid ); XP_ASSERT( SQLITE_OK == result );
cGlobals->rowid = rowid; result = sqlite3_bind_zeroblob( stmt, 1 /*col 0 ??*/, len );
sqlite3_finalize( stmt ); XP_ASSERT( SQLITE_OK == result );
result = sqlite3_step( stmt );
XP_ASSERT( SQLITE_DONE == result );
if ( -1 == selRow ) { /* new row; need to insert blob first */
selRow = sqlite3_last_insert_rowid( pDb );
XP_LOGF( "%s: new rowid: %lld", __func__, selRow );
cGlobals->selRow = selRow;
} }
sqlite3_blob* blob; sqlite3_blob* blob;
result = sqlite3_blob_open( pDb, "main", "games", "game", result = sqlite3_blob_open( pDb, "main", "games", "game",
rowid, 1 /*flags: writeable*/, &blob ); selRow, 1 /*flags: writeable*/, &blob );
XP_ASSERT( SQLITE_OK == result ); XP_ASSERT( SQLITE_OK == result );
const XP_U8* ptr = stream_getPtr( stream ); const XP_U8* ptr = stream_getPtr( stream );
result = sqlite3_blob_write( blob, ptr, len, 0 ); result = sqlite3_blob_write( blob, ptr, len, 0 );
@ -128,3 +136,21 @@ getGameName( GTKGamesGlobals* XP_UNUSED(gg), const sqlite3_int64* rowid,
snprintf( buf, len, "Game %lld", *rowid ); snprintf( buf, len, "Game %lld", *rowid );
LOG_RETURNF( "%s", buf ); LOG_RETURNF( "%s", buf );
} }
XP_Bool
loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid )
{
char buf[256];
snprintf( buf, sizeof(buf), "SELECT game from games WHERE rowid = %lld", rowid );
sqlite3_stmt *ppStmt;
int result = sqlite3_prepare_v2( pDb, buf, -1, &ppStmt, NULL );
XP_ASSERT( SQLITE_OK == result );
result = sqlite3_step( ppStmt );
XP_ASSERT( SQLITE_ROW == result );
const void* ptr = sqlite3_column_blob( ppStmt, 0 );
int size = sqlite3_column_bytes( ppStmt, 0 );
stream_putBytes( stream, ptr, size );
sqlite3_finalize( ppStmt );
return XP_TRUE;
}

View file

@ -36,6 +36,6 @@ void writeToDB( XWStreamCtxt* stream, void* closure );
GSList* listGames( GTKGamesGlobals* gg ); GSList* listGames( GTKGamesGlobals* gg );
void getGameName( GTKGamesGlobals* gg, const sqlite3_int64* rowid, void getGameName( GTKGamesGlobals* gg, const sqlite3_int64* rowid,
XP_UCHAR* buf, XP_U16 len ); XP_UCHAR* buf, XP_U16 len );
XP_Bool loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid );
#endif #endif

View file

@ -63,6 +63,7 @@
#include "gtkdraw.h" #include "gtkdraw.h"
#include "memstream.h" #include "memstream.h"
#include "filestream.h" #include "filestream.h"
#include "gamesdb.h"
/* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */ /* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */
static void setCtrlsForTray( GtkAppGlobals* globals ); static void setCtrlsForTray( GtkAppGlobals* globals );
@ -396,7 +397,8 @@ createOrLoadObjects( GtkAppGlobals* globals )
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
#endif #endif
LaunchParams* params = globals->cGlobals.params; CommonGlobals* cGlobals = &globals->cGlobals;
LaunchParams* params = cGlobals->params;
globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area, globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area,
globals ); globals );
@ -415,11 +417,19 @@ createOrLoadObjects( GtkAppGlobals* globals )
}; };
if ( !!params->fileName && file_exists( params->fileName ) ) { if ( !!params->fileName && file_exists( params->fileName ) ) {
stream = streamFromFile( &globals->cGlobals, params->fileName, globals ); stream = streamFromFile( cGlobals, params->fileName, globals );
#ifdef USE_SQLITE #ifdef USE_SQLITE
} else if ( !!params->dbFileName && file_exists( params->dbFileName ) ) { } else if ( !!params->dbFileName && file_exists( params->dbFileName ) ) {
stream = streamFromDB( &globals->cGlobals, globals ); stream = streamFromDB( cGlobals, globals );
#endif #endif
} else if ( !!cGlobals->pDb && 0 <= cGlobals->selRow ) {
stream = mem_stream_make( MPPARM(params->util->mpool)
params->vtMgr,
cGlobals, CHANNEL_NONE, NULL );
if ( !loadGame( stream, cGlobals->pDb, cGlobals->selRow ) ) {
stream_destroy( stream );
stream = NULL;
}
} }
if ( !!stream ) { if ( !!stream ) {
@ -2501,6 +2511,8 @@ makeNewGame( GtkAppGlobals* globals )
globals->cGlobals.params->dict = globals->cGlobals.params->dict =
linux_dictionary_make( MEMPOOL globals->cGlobals.params, linux_dictionary_make( MEMPOOL globals->cGlobals.params,
gi->dictName, XP_TRUE ); gi->dictName, XP_TRUE );
} else {
success = XP_FALSE;
} }
return success; return success;
} }

View file

@ -27,9 +27,29 @@
enum { ROW_ITEM, NAME_ITEM, N_ITEMS }; enum { ROW_ITEM, NAME_ITEM, N_ITEMS };
static void /* Prototype for selection handler callback */
init_games_list( GtkWidget* list ) static void
tree_selection_changed_cb( GtkTreeSelection* selection, gpointer data )
{ {
LOG_FUNC();
GTKGamesGlobals* gg = (GTKGamesGlobals*)data;
GtkTreeIter iter;
GtkTreeModel *model;
gchar *row;
if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) {
gtk_tree_model_get( model, &iter, ROW_ITEM, &row, -1 );
sscanf( row, "%lld", &gg->selRow );
g_print ("You selected row %s (parsed: %lld)\n", row, gg->selRow );
g_free( row );
}
}
static GtkWidget*
init_games_list( GTKGamesGlobals* gg )
{
GtkWidget* list = gtk_tree_view_new();
GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn* column = GtkTreeViewColumn* column =
gtk_tree_view_column_new_with_attributes( "Row", renderer, "text", gtk_tree_view_column_new_with_attributes( "Row", renderer, "text",
@ -45,6 +65,13 @@ init_games_list( GtkWidget* list )
G_TYPE_STRING, G_TYPE_STRING ); G_TYPE_STRING, G_TYPE_STRING );
gtk_tree_view_set_model( GTK_TREE_VIEW(list), GTK_TREE_MODEL(store) ); gtk_tree_view_set_model( GTK_TREE_VIEW(list), GTK_TREE_MODEL(store) );
g_object_unref( store ); g_object_unref( store );
GtkTreeSelection* select =
gtk_tree_view_get_selection( GTK_TREE_VIEW (list) );
gtk_tree_selection_set_mode( select, GTK_SELECTION_SINGLE );
g_signal_connect( G_OBJECT(select), "changed",
G_CALLBACK (tree_selection_changed_cb), gg );
return list;
} }
static void static void
@ -77,10 +104,25 @@ handle_newgame_button( GtkWidget* XP_UNUSED(widget), void* closure )
} else { } else {
GtkWidget* gameWindow = globals->window; GtkWidget* gameWindow = globals->window;
globals->cGlobals.pDb = gg->pDb; globals->cGlobals.pDb = gg->pDb;
globals->cGlobals.selRow = -1;
gtk_widget_show( gameWindow ); gtk_widget_show( gameWindow );
} }
} }
static void
handle_open_button( GtkWidget* XP_UNUSED(widget), void* closure )
{
GTKGamesGlobals* gg = (GTKGamesGlobals*)closure;
if ( -1 != gg->selRow ) {
gg->params->needsNewGame = XP_FALSE;
GtkAppGlobals* globals = malloc( sizeof(*globals) );
initGlobals( globals, gg->params );
globals->cGlobals.pDb = gg->pDb;
globals->cGlobals.selRow = gg->selRow;
gtk_widget_show( globals->window );
}
}
static void static void
handle_quit_button( GtkWidget* XP_UNUSED(widget), gpointer data ) handle_quit_button( GtkWidget* XP_UNUSED(widget), gpointer data )
{ {
@ -111,9 +153,9 @@ makeGamesWindow( GTKGamesGlobals* gg )
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_add( GTK_CONTAINER(window), vbox ); gtk_container_add( GTK_CONTAINER(window), vbox );
gtk_widget_show( vbox ); gtk_widget_show( vbox );
GtkWidget* list = gtk_tree_view_new(); GtkWidget* list = init_games_list( gg );
gtk_container_add( GTK_CONTAINER(vbox), list ); gtk_container_add( GTK_CONTAINER(vbox), list );
init_games_list( list );
gtk_widget_show( list ); gtk_widget_show( list );
GSList* games = listGames( gg ); GSList* games = listGames( gg );
@ -134,6 +176,11 @@ makeGamesWindow( GTKGamesGlobals* gg )
G_CALLBACK(handle_newgame_button), gg ); G_CALLBACK(handle_newgame_button), gg );
gtk_widget_show( button ); gtk_widget_show( button );
button = gtk_button_new_with_label( "Open" );
gtk_container_add( GTK_CONTAINER(hbox), button );
g_signal_connect( GTK_OBJECT(button), "clicked",
G_CALLBACK(handle_open_button), gg );
gtk_widget_show( button );
button = gtk_button_new_with_label( "Quit" ); button = gtk_button_new_with_label( "Quit" );
gtk_container_add( GTK_CONTAINER(hbox), button ); gtk_container_add( GTK_CONTAINER(hbox), button );
g_signal_connect( GTK_OBJECT(button), "clicked", g_signal_connect( GTK_OBJECT(button), "clicked",
@ -148,6 +195,7 @@ int
gtkmain( LaunchParams* params ) gtkmain( LaunchParams* params )
{ {
GTKGamesGlobals gg = {0}; GTKGamesGlobals gg = {0};
gg.selRow = -1;
gg.params = params; gg.params = params;
XP_LOGF( "%s: I'M HERE!!! (calling makeGamesDB())", __func__ ); XP_LOGF( "%s: I'M HERE!!! (calling makeGamesDB())", __func__ );
gg.pDb = openGamesDB(); gg.pDb = openGamesDB();

View file

@ -261,7 +261,7 @@ saveGame( CommonGlobals* cGlobals )
if ( !!cGlobals->params->fileName || !!cGlobals->pDb ) { if ( !!cGlobals->params->fileName || !!cGlobals->pDb ) {
XP_Bool doSave = XP_TRUE; XP_Bool doSave = XP_TRUE;
XP_Bool newGame = !file_exists( cGlobals->params->fileName ) XP_Bool newGame = !file_exists( cGlobals->params->fileName )
|| 0 == cGlobals->rowid; || -1 == cGlobals->selRow;
/* don't fail to save first time! */ /* don't fail to save first time! */
if ( 0 < cGlobals->params->saveFailPct && !newGame ) { if ( 0 < cGlobals->params->saveFailPct && !newGame ) {
XP_U16 pct = XP_RANDOM() % 100; XP_U16 pct = XP_RANDOM() % 100;

View file

@ -169,11 +169,11 @@ struct CommonGlobals {
CommonPrefs cp; CommonPrefs cp;
XWGame game; XWGame game;
sqlite3_int64 rowid;
XP_U16 lastNTilesToUse; XP_U16 lastNTilesToUse;
XP_U16 lastStreamSize; XP_U16 lastStreamSize;
XP_Bool manualFinal; /* use asked for final scores */ XP_Bool manualFinal; /* use asked for final scores */
sqlite3* pDb; sqlite3* pDb;
sqlite3_int64 selRow;
SocketChangedFunc socketChanged; SocketChangedFunc socketChanged;
void* socketChangedClosure; void* socketChangedClosure;
@ -211,6 +211,7 @@ struct CommonGlobals {
typedef struct _GTKGamesGlobals { typedef struct _GTKGamesGlobals {
sqlite3* pDb; sqlite3* pDb;
sqlite3_int64 selRow;
LaunchParams* params; LaunchParams* params;
} GTKGamesGlobals; } GTKGamesGlobals;