From e0dc83ed70e23488a1cac3c1600d38415814b5e7 Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 5 Jan 2013 16:08:47 -0800 Subject: [PATCH] rest of what I just meant to commit. --- xwords4/common/mempool.c | 18 +++--- xwords4/linux/gamesdb.c | 47 +++++++++++++-- xwords4/linux/gamesdb.h | 4 ++ xwords4/linux/gtkboard.c | 119 ++++++++++++++++++++++--------------- xwords4/linux/gtkmain.c | 43 ++++++++++++-- xwords4/linux/gtknewgame.c | 46 +++++++------- xwords4/linux/gtknewgame.h | 9 +-- xwords4/linux/linuxmain.c | 32 +++++----- xwords4/linux/linuxmain.h | 4 +- xwords4/linux/main.h | 4 ++ 10 files changed, 217 insertions(+), 109 deletions(-) diff --git a/xwords4/common/mempool.c b/xwords4/common/mempool.c index 799cce0a8..206c4de04 100644 --- a/xwords4/common/mempool.c +++ b/xwords4/common/mempool.c @@ -78,19 +78,21 @@ checkIsText( MemPoolEntry* entry ) { unsigned char* txt = (unsigned char*)entry->ptr; XP_U32 len = entry->size; + char* result = NULL; - while ( len-- ) { - unsigned char c = *txt++; - if ( c < 32 || c > 127 ) { - if ( len == 0 && c == '\0' ) { - return (char*)entry->ptr; - } else { - return (char*)NULL; + if ( 0 < len ) { + while ( len-- ) { + unsigned char c = *txt++; + if ( c < 32 || c > 127 ) { + if ( len == 0 && c == '\0' ) { + result = (char*)entry->ptr; + } + break; } } } - return (char*)NULL; + return result; } /* checkIsText */ #endif diff --git a/xwords4/linux/gamesdb.c b/xwords4/linux/gamesdb.c index cceee713d..105d45999 100644 --- a/xwords4/linux/gamesdb.c +++ b/xwords4/linux/gamesdb.c @@ -1,6 +1,6 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE -j3"; -*- */ +/* -*-mode: compile-command: "make MEMDEBUG=TRUE -j3"; -*- */ /* - * Copyright 2000-2012 by Eric House (xwords@eehouse.org). All rights + * Copyright 2000-2013 by Eric House (xwords@eehouse.org). All rights * reserved. * * This program is free software; you can redistribute it and/or @@ -18,10 +18,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include - -#include "comtypes.h" #include "gamesdb.h" +#include "main.h" #define DB_NAME "games.db" @@ -51,3 +49,42 @@ closeGamesDB( sqlite3* pDb ) sqlite3_close( pDb ); XP_LOGF( "%s finished", __func__ ); } + +void +writeToDB( XWStreamCtxt* stream, void* closure ) +{ + int result; + CommonGlobals* cGlobals = (CommonGlobals*)closure; + sqlite3_int64 rowid = cGlobals->rowid; + sqlite3* pDb = cGlobals->pDb; + XP_U16 len = stream_getSize( stream ); + + sqlite3_stmt* stmt = NULL; + if ( 0 == rowid ) { /* new row; need to insert blob first */ + const char* txt = "INSERT INTO games (game) VALUES (?)"; + result = sqlite3_prepare_v2( pDb, txt, -1, &stmt, NULL ); + XP_ASSERT( SQLITE_OK == result ); + result = sqlite3_bind_zeroblob( stmt, 1 /*col 0 ??*/, len ); + XP_ASSERT( SQLITE_OK == result ); + result = sqlite3_step( stmt ); + XP_ASSERT( SQLITE_DONE == result ); + + rowid = sqlite3_last_insert_rowid( pDb ); + XP_LOGF( "%s: new rowid: %lld", __func__, rowid ); + cGlobals->rowid = rowid; + sqlite3_finalize( stmt ); + } + + sqlite3_blob* blob; + result = sqlite3_blob_open( pDb, "main", "games", "game", + rowid, 1 /*flags: writeable*/, &blob ); + XP_ASSERT( SQLITE_OK == result ); + const XP_U8* ptr = stream_getPtr( stream ); + result = sqlite3_blob_write( blob, ptr, len, 0 ); + XP_ASSERT( SQLITE_OK == result ); + result = sqlite3_blob_close( blob ); + XP_ASSERT( SQLITE_OK == result ); + if ( !!stmt ) { + sqlite3_finalize( stmt ); + } +} diff --git a/xwords4/linux/gamesdb.h b/xwords4/linux/gamesdb.h index a76deb6cc..5a7c6c15b 100644 --- a/xwords4/linux/gamesdb.h +++ b/xwords4/linux/gamesdb.h @@ -23,7 +23,11 @@ #include +#include "comtypes.h" + sqlite3* openGamesDB( void ); void closeGamesDB( sqlite3* dbp ); +void writeToDB( XWStreamCtxt* stream, void* closure ); + #endif diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index 695ac6ba7..87267d110 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -395,8 +395,6 @@ createOrLoadObjects( GtkAppGlobals* globals ) XP_Bool opened = XP_FALSE; #ifndef XWFEATURE_STANDALONE_ONLY - DeviceRole serverRole = globals->cGlobals.params->serverRole; - XP_Bool isServer = serverRole != SERVER_ISCLIENT; #endif LaunchParams* params = globals->cGlobals.params; @@ -500,15 +498,20 @@ createOrLoadObjects( GtkAppGlobals* globals ) params->gi.allowHintRect = params->allowHintRect; #endif + if ( params->needsNewGame ) { new_game_impl( globals, XP_FALSE ); #ifndef XWFEATURE_STANDALONE_ONLY - } else if ( !isServer ) { - XWStreamCtxt* stream = - mem_stream_make( MEMPOOL params->vtMgr, &globals->cGlobals, CHANNEL_NONE, - sendOnClose ); - server_initClientConnection( globals->cGlobals.game.server, - stream ); + } else { + DeviceRole serverRole = globals->cGlobals.params->gi.serverRole; + if ( serverRole == SERVER_ISCLIENT ) { + XWStreamCtxt* stream = + mem_stream_make( MEMPOOL params->vtMgr, + &globals->cGlobals, CHANNEL_NONE, + sendOnClose ); + server_initClientConnection( globals->cGlobals.game.server, + stream ); + } #endif } } @@ -670,9 +673,12 @@ handle_client_event( GtkWidget *widget, GdkEventClient *event, #endif static void -quit( void ) +destroy_window( GtkWidget* XP_UNUSED(widget), gpointer data ) { - gtk_main_quit(); + LOG_FUNC(); + GtkAppGlobals* globals = (GtkAppGlobals*)data; + saveGame( &globals->cGlobals ); + // gtk_main_quit(); } static void @@ -786,9 +792,9 @@ new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg ) comms_getInitialAddr( &addr, RELAY_NAME_DEFAULT, RELAY_PORT_DEFAULT ); } - success = newGameDialog( globals, &addr, XP_TRUE, fireConnDlg ); + CurGameInfo* gi = &globals->cGlobals.params->gi; + success = newGameDialog( globals, gi, &addr, XP_TRUE, fireConnDlg ); if ( success ) { - CurGameInfo* gi = &globals->cGlobals.params->gi; #ifndef XWFEATURE_STANDALONE_ONLY XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT; #endif @@ -803,22 +809,22 @@ new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg ) if ( !game_reset( MEMPOOL &globals->cGlobals.game, gi, globals->cGlobals.params->util, &globals->cGlobals.cp, &procs ) ) { - if ( NULL == globals->draw ) { - globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area, - globals ); - } - game_makeNewGame( MEMPOOL &globals->cGlobals.game, gi, - globals->cGlobals.params->util, - (DrawCtx*)globals->draw, - &globals->cGlobals.cp, &procs, - globals->cGlobals.params->gameSeed ); - ModelCtxt* model = globals->cGlobals.game.model; - if ( NULL == model_getDictionary( model ) ) { - DictionaryCtxt* dict = - linux_dictionary_make( MEMPOOL globals->cGlobals.params, - gi->dictName, XP_TRUE ); - model_setDictionary( model, dict ); - } + /* if ( NULL == globals->draw ) { */ + /* globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area, */ + /* globals ); */ + /* } */ + /* game_makeNewGame( MEMPOOL &globals->cGlobals.game, gi, */ + /* globals->cGlobals.params->util, */ + /* (DrawCtx*)globals->draw, */ + /* &globals->cGlobals.cp, &procs, */ + /* globals->cGlobals.params->gameSeed ); */ + /* ModelCtxt* model = globals->cGlobals.game.model; */ + /* if ( NULL == model_getDictionary( model ) ) { */ + /* DictionaryCtxt* dict = */ + /* linux_dictionary_make( MEMPOOL globals->cGlobals.params, */ + /* gi->dictName, XP_TRUE ); */ + /* model_setDictionary( model, dict ); */ + /* } */ } #ifndef XWFEATURE_STANDALONE_ONLY @@ -858,7 +864,8 @@ game_info( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals ) /* Anything to do if OK is clicked? Changed names etc. already saved. Try server_do in case one's become a robot. */ - if ( newGameDialog( globals, &addr, XP_FALSE, XP_FALSE ) ) { + CurGameInfo* gi = &globals->cGlobals.params->gi; + if ( newGameDialog( globals, gi, &addr, XP_FALSE, XP_FALSE ) ) { if ( server_do( globals->cGlobals.game.server ) ) { board_draw( globals->cGlobals.game.board ); } @@ -868,11 +875,13 @@ game_info( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals ) static void load_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* XP_UNUSED(globals) ) { + XP_ASSERT(0); } /* load_game */ static void save_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* XP_UNUSED(globals) ) { + XP_ASSERT(0); } /* save_game */ #ifdef XWFEATURE_CHANGEDICT @@ -1478,7 +1487,7 @@ gtk_util_notifyGameOver( XW_UtilCtxt* uc, XP_S16 quitter ) if ( cGlobals->params->quitAfter >= 0 ) { sleep( cGlobals->params->quitAfter ); - quit(); + destroy_window( NULL, globals ); } else if ( cGlobals->params->undoWhenDone ) { server_handleUndo( cGlobals->game.server, 0 ); board_draw( cGlobals->game.board ); @@ -2298,25 +2307,25 @@ handle_sigintterm( int XP_UNUSED(sig) ) gtk_main_quit(); } -int -board_main( LaunchParams* params ) -{ - GtkAppGlobals globals; - initGlobals( &globals, params ); +/* int */ +/* board_main( LaunchParams* params ) */ +/* { */ +/* GtkAppGlobals globals; */ +/* initGlobals( &globals, params ); */ - if ( !!params->pipe && !!params->fileName ) { - read_pipe_then_close( &globals.cGlobals, NULL ); - } else { - gtk_widget_show( globals.window ); +/* if ( !!params->pipe && !!params->fileName ) { */ +/* read_pipe_then_close( &globals.cGlobals, NULL ); */ +/* } else { */ +/* gtk_widget_show( globals.window ); */ - gtk_main(); - } - /* MONCONTROL(1); */ +/* gtk_main(); */ +/* } */ +/* /\* MONCONTROL(1); *\/ */ - cleanup( &globals ); +/* cleanup( &globals ); */ - return 0; -} /* gtkmain */ +/* return 0; */ +/* } */ void initGlobals( GtkAppGlobals* globals, LaunchParams* params ) @@ -2379,7 +2388,7 @@ initGlobals( GtkAppGlobals* globals, LaunchParams* params ) gtk_widget_show( vbox ); g_signal_connect( G_OBJECT (window), "destroy", - G_CALLBACK( quit ), &globals ); + G_CALLBACK( destroy_window ), globals ); menubar = makeMenus( globals ); gtk_box_pack_start( GTK_BOX(vbox), menubar, FALSE, TRUE, 0); @@ -2387,7 +2396,7 @@ initGlobals( GtkAppGlobals* globals, LaunchParams* params ) #ifndef XWFEATURE_STANDALONE_ONLY dropCheck = gtk_check_button_new_with_label( "drop incoming messages" ); g_signal_connect( GTK_OBJECT(dropCheck), - "toggled", G_CALLBACK(drop_msg_toggle), &globals ); + "toggled", G_CALLBACK(drop_msg_toggle), globals ); gtk_box_pack_start( GTK_BOX(vbox), dropCheck, FALSE, TRUE, 0); gtk_widget_show( dropCheck ); #endif @@ -2479,7 +2488,21 @@ freeGlobals( GtkAppGlobals* globals ) XP_Bool makeNewGame( GtkAppGlobals* globals ) { - return new_game_impl( globals, XP_FALSE ); + CommsAddrRec addr; + if ( !!globals->cGlobals.game.comms ) { + comms_getAddr( globals->cGlobals.game.comms, &addr ); + } else { + comms_getInitialAddr( &addr, RELAY_NAME_DEFAULT, RELAY_PORT_DEFAULT ); + } + + CurGameInfo* gi = &globals->cGlobals.params->gi; + XP_Bool success = newGameDialog( globals, gi, &addr, XP_TRUE, XP_FALSE ); + if ( success && !!gi->dictName && !globals->cGlobals.params->dict ) { + globals->cGlobals.params->dict = + linux_dictionary_make( MEMPOOL globals->cGlobals.params, + gi->dictName, XP_TRUE ); + } + return success; } #endif /* PLATFORM_GTK */ diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index 842557aef..4560e3641 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -25,22 +25,20 @@ #include "gtkboard.h" #include "linuxmain.h" -enum { NAME_ITEM, N_ITEMS }; +enum { ROW_ITEM, N_ITEMS }; typedef struct _GTKGamesGlobals { sqlite3* pDb; - GtkAppGlobals globals; LaunchParams* params; } GTKGamesGlobals; - static void init_games_list( GtkWidget* list ) { GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Games", renderer, - "text", NAME_ITEM, NULL ); + "row", ROW_ITEM, NULL ); gtk_tree_view_append_column( GTK_TREE_VIEW(list), column ); GtkListStore* store = gtk_list_store_new( N_ITEMS, G_TYPE_STRING ); gtk_tree_view_set_model( GTK_TREE_VIEW(list), GTK_TREE_MODEL(store) ); @@ -53,33 +51,66 @@ handle_newgame_button( GtkWidget* XP_UNUSED(widget), void* closure ) GTKGamesGlobals* gg = (GTKGamesGlobals*)closure; XP_LOGF( "%s called", __func__ ); GtkAppGlobals* globals = malloc( sizeof(*globals) ); + gg->params->needsNewGame = XP_FALSE; initGlobals( globals, gg->params ); if ( !makeNewGame( globals ) ) { freeGlobals( globals ); } else { GtkWidget* gameWindow = globals->window; + globals->cGlobals.pDb = gg->pDb; gtk_widget_show( gameWindow ); } } +static void +handle_quit_button( GtkWidget* XP_UNUSED(widget), gpointer data ) +{ + GTKGamesGlobals* gg = (GTKGamesGlobals*)data; + gg = gg; + gtk_main_quit(); +} + +static void +handle_destroy( GtkWidget* XP_UNUSED(widget), gpointer data ) +{ + LOG_FUNC(); + GTKGamesGlobals* gg = (GTKGamesGlobals*)data; + gg = gg; + gtk_main_quit(); +} + + static GtkWidget* makeGamesWindow( GTKGamesGlobals* gg ) { GtkWidget* window; window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - + g_signal_connect( G_OBJECT(window), "destroy", + G_CALLBACK(handle_destroy), gg ); + GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); gtk_container_add( GTK_CONTAINER(window), vbox ); gtk_widget_show( vbox ); GtkWidget* list = gtk_tree_view_new(); gtk_container_add( GTK_CONTAINER(vbox), list ); init_games_list( list ); + gtk_widget_show( list ); + + GtkWidget* hbox = gtk_hbox_new( FALSE, 0 ); + gtk_widget_show( hbox ); + gtk_container_add( GTK_CONTAINER(vbox), hbox ); GtkWidget* button = gtk_button_new_with_label( "New Game" ); - gtk_container_add( GTK_CONTAINER(vbox), button ); + gtk_container_add( GTK_CONTAINER(hbox), button ); g_signal_connect( GTK_OBJECT(button), "clicked", G_CALLBACK(handle_newgame_button), gg ); gtk_widget_show( button ); + + button = gtk_button_new_with_label( "Quit" ); + gtk_container_add( GTK_CONTAINER(hbox), button ); + g_signal_connect( GTK_OBJECT(button), "clicked", + G_CALLBACK(handle_quit_button), gg ); + gtk_widget_show( button ); gtk_widget_show( window ); return window; diff --git a/xwords4/linux/gtknewgame.c b/xwords4/linux/gtknewgame.c index b9f6fc04d..d5acd03cd 100644 --- a/xwords4/linux/gtknewgame.c +++ b/xwords4/linux/gtknewgame.c @@ -1,6 +1,6 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE"; -*- */ +/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */ /* - * Copyright 2001-2008 by Eric House (xwords@eehouse.org). All rights + * Copyright 2001-2013 by Eric House (xwords@eehouse.org). All rights * reserved. * * This program is free software; you can redistribute it and/or @@ -33,6 +33,7 @@ typedef struct GtkNewGameState { GtkAppGlobals* globals; + CurGameInfo* gi; NewGameCtx* newGameCtxt; CommsAddrRec addr; @@ -248,7 +249,7 @@ makeNewGameDialog( GtkNewGameState* state ) nPlayersCombo = gtk_combo_box_new_text(); state->nPlayersCombo = nPlayersCombo; - gi = &state->globals->cGlobals.params->gi; + gi = state->gi; for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) { char buf[2] = { ii + '1', '\0' }; @@ -352,16 +353,21 @@ makeNewGameDialog( GtkNewGameState* state ) gtk_box_pack_start( GTK_BOX(hbox), dictCombo, FALSE, TRUE, 0 ); GSList* dicts = listDicts( state->globals->cGlobals.params ); - for ( GSList* iter = dicts; !!iter; iter = iter->next ) { - gtk_combo_box_append_text( GTK_COMBO_BOX(dictCombo), iter->data ); + GSList* iter; + for ( iter = dicts, ii = 0; !!iter; iter = iter->next, ++ii ) { + const gchar* name = iter->data; + gtk_combo_box_append_text( GTK_COMBO_BOX(dictCombo), name ); + if ( !!gi->dictName && !strcmp( name, gi->dictName ) ) { + gtk_combo_box_set_active( GTK_COMBO_BOX(dictCombo), ii ); + } } g_slist_free( dicts ); - if ( !!gi->dictName ) { - gtk_box_pack_start( GTK_BOX(hbox), - gtk_label_new(gi->dictName), - FALSE, TRUE, 0 ); - } + /* if ( !!gi->dictName ) { */ + /* gtk_box_pack_start( GTK_BOX(hbox), */ + /* gtk_label_new(gi->dictName), */ + /* FALSE, TRUE, 0 ); */ + /* } */ gtk_widget_show( hbox ); @@ -538,13 +544,14 @@ gtk_newgame_attr_set( void* closure, NewGameAttr attr, NGValue value ) } gboolean -newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame, - XP_Bool fireConnDlg ) +newGameDialog( GtkAppGlobals* globals, CurGameInfo* gi, CommsAddrRec* addr, + XP_Bool isNewGame, XP_Bool fireConnDlg ) { GtkNewGameState state; XP_MEMSET( &state, 0, sizeof(state) ); state.globals = globals; + state.gi = gi; state.newGameCtxt = newg_make( MPPARM(globals->cGlobals.params ->util->mpool) isNewGame, @@ -564,25 +571,22 @@ newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame, state.revert = FALSE; state.loaded = XP_FALSE; - state.nCols = globals->cGlobals.params->gi.boardSize; - state.role = globals->cGlobals.params->gi.serverRole; + state.nCols = gi->boardSize; + state.role = gi->serverRole; XP_MEMCPY( &state.addr, addr, sizeof(state.addr) ); dialog = makeNewGameDialog( &state ); - newg_load( state.newGameCtxt, - &globals->cGlobals.params->gi ); + newg_load( state.newGameCtxt, gi ); state.loaded = XP_TRUE; gtk_main(); if ( !state.cancelled && !state.revert ) { - if ( newg_store( state.newGameCtxt, &globals->cGlobals.params->gi, - XP_TRUE ) ) { - globals->cGlobals.params->gi.boardSize = state.nCols; + if ( newg_store( state.newGameCtxt, gi, XP_TRUE ) ) { + gi->boardSize = state.nCols; replaceStringIfDifferent( globals->cGlobals.params->util->mpool, - &globals->cGlobals.params->gi.dictName, - state.dict ); + &gi->dictName, state.dict ); } else { /* Do it again if we warned user of inconsistency. */ state.revert = XP_TRUE; diff --git a/xwords4/linux/gtknewgame.h b/xwords4/linux/gtknewgame.h index 3a97bd2ac..dad9e6074 100644 --- a/xwords4/linux/gtknewgame.h +++ b/xwords4/linux/gtknewgame.h @@ -1,6 +1,6 @@ -/* -*- compile-command: "make MEMDEBUG=TRUE"; -*- */ +/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */ /* - * Copyright 2000-2009 by Eric House (xwords@eehouse.org). All rights + * Copyright 2000-2013 by Eric House (xwords@eehouse.org). All rights * reserved. * * This program is free software; you can redistribute it and/or @@ -26,8 +26,9 @@ #include "gtkboard.h" -gboolean newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, - XP_Bool isNewGame, XP_Bool fireConnDlg ); +gboolean newGameDialog( GtkAppGlobals* globals, CurGameInfo* gi, + CommsAddrRec* addr, XP_Bool isNewGame, + XP_Bool fireConnDlg ); #endif /* _GTKNEWGAME_H_ */ #endif /* PLATFORM_GTK */ diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index 81bb34651..bbb4cd3e1 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -57,6 +57,7 @@ #include "linuxudp.h" #include "dictiter.h" #include "main.h" +#include "gamesdb.h" #ifdef PLATFORM_NCURSES # include "cursesmain.h" #endif @@ -130,7 +131,8 @@ streamFromDB( CommonGlobals* cGlobals, void* closure ) XP_U8 buf[size]; res = sqlite3_blob_read( ppBlob, buf, size, 0 ); if ( SQLITE_OK == res ) { - stream = mem_stream_make( MPPARM(params->util->mpool) params->vtMgr, + stream = mem_stream_make( MPPARM(params->util->mpool) + params->vtMgr, closure, CHANNEL_NONE, NULL ); stream_putBytes( stream, buf, size ); } @@ -255,23 +257,26 @@ strFromStream( XWStreamCtxt* stream ) void saveGame( CommonGlobals* cGlobals ) { - if ( !!cGlobals->params->fileName ) { + LOG_FUNC(); + if ( !!cGlobals->params->fileName || !!cGlobals->pDb ) { XP_Bool doSave = XP_TRUE; - if ( 0 < cGlobals->params->saveFailPct - /* don't fail to save first time! */ - && file_exists( cGlobals->params->fileName ) ) { + XP_Bool newGame = !file_exists( cGlobals->params->fileName ) + || 0 == cGlobals->rowid; + /* don't fail to save first time! */ + if ( 0 < cGlobals->params->saveFailPct && !newGame ) { XP_U16 pct = XP_RANDOM() % 100; doSave = pct >= cGlobals->params->saveFailPct; } if ( doSave ) { XWStreamCtxt* outStream; - + MemStreamCloseCallback onClose = !!cGlobals->pDb? + writeToDB : writeToFile; outStream = mem_stream_make_sized( MPPARM(cGlobals->params->util->mpool) cGlobals->params->vtMgr, cGlobals->lastStreamSize, - cGlobals, 0, writeToFile ); + cGlobals, 0, onClose ); stream_open( outStream ); game_saveToStream( &cGlobals->game, @@ -1507,14 +1512,13 @@ listDicts( const LaunchParams *params ) return result; } -void +static void initParams( LaunchParams* params ) { memset( params, 0, sizeof(*params) ); - params->util = malloc( sizeof(params->util) ); - - XP_MEMSET( params->util, 0, sizeof(params->util) ); + params->util = calloc( 1, sizeof(*params->util) ); + /* XP_MEMSET( params->util, 0, sizeof(params->util) ); */ #ifdef MEM_DEBUG params->util->mpool = mpool_make(); @@ -1529,11 +1533,11 @@ initParams( LaunchParams* params ) #endif } -void +static void freeParams( LaunchParams* params ) { - vtmgr_destroy( MPPARM(params->util->mpool) params->vtMgr ); linux_util_vt_destroy( params->util ); + vtmgr_destroy( MPPARM(params->util->mpool) params->vtMgr ); mpool_destroy( params->util->mpool ); @@ -1596,8 +1600,6 @@ main( int argc, char** argv ) #endif initParams( &mainParams ); - /* fprintf( stdout, "press to start\n" ); */ - /* (void)fgetc( stdin ); */ /* defaults */ #ifdef XWFEATURE_RELAY diff --git a/xwords4/linux/linuxmain.h b/xwords4/linux/linuxmain.h index e4d4eb526..f6cb25219 100644 --- a/xwords4/linux/linuxmain.h +++ b/xwords4/linux/linuxmain.h @@ -94,7 +94,7 @@ void setOneSecondTimer( CommonGlobals* cGlobals ); # define setOneSecondTimer( cGlobals ) #endif -void initParams( LaunchParams* params ); -void freeParams( LaunchParams* params ); +/* void initParams( LaunchParams* params ); */ +/* void freeParams( LaunchParams* params ); */ #endif diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 028ea0b0a..ecf34680d 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -25,6 +25,8 @@ # include /* for bdaddr_t, which should move */ #endif +#include + #include "comtypes.h" #include "util.h" #include "game.h" @@ -167,9 +169,11 @@ struct CommonGlobals { CommonPrefs cp; XWGame game; + sqlite3_int64 rowid; XP_U16 lastNTilesToUse; XP_U16 lastStreamSize; XP_Bool manualFinal; /* use asked for final scores */ + sqlite3* pDb; SocketChangedFunc socketChanged; void* socketChangedClosure;