mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-29 10:26:36 +01:00
toward snapshots in gtk version
Add new "snap" blob to db and pixbuf column to games display table, and add code to store and retrieve from db. What's stored now is a hard-coded file, so next up is generating an actual snapshot from the game.
This commit is contained in:
parent
b4393d5965
commit
aeee2d801a
4 changed files with 84 additions and 14 deletions
|
@ -42,6 +42,7 @@ openGamesDB( const char* dbName )
|
|||
"CREATE TABLE games ( "
|
||||
"rowid INTEGER PRIMARY KEY AUTOINCREMENT"
|
||||
",game BLOB"
|
||||
",snap BLOB"
|
||||
",inviteInfo BLOB"
|
||||
",room VARCHAR(32)"
|
||||
",connvia VARCHAR(32)"
|
||||
|
@ -73,12 +74,11 @@ closeGamesDB( sqlite3* pDb )
|
|||
}
|
||||
|
||||
static sqlite3_int64
|
||||
writeBlobColumn( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 curRow,
|
||||
const char* column )
|
||||
writeBlobColumnData( const XP_U8* data, gsize len, XP_U16 strVersion, sqlite3* pDb,
|
||||
sqlite3_int64 curRow, const char* column )
|
||||
{
|
||||
XP_LOGF( "%s(col=%s)", __func__, column );
|
||||
int result;
|
||||
/* size includes stream version as header */
|
||||
XP_U16 len = stream_getSize( stream );
|
||||
char buf[256];
|
||||
char* query;
|
||||
|
||||
|
@ -114,12 +114,10 @@ writeBlobColumn( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 curRow,
|
|||
result = sqlite3_blob_open( pDb, "main", "games", column,
|
||||
curRow, 1 /*flags: writeable*/, &blob );
|
||||
assertPrintResult( pDb, result, SQLITE_OK );
|
||||
XP_U16 strVersion = stream_getVersion( stream );
|
||||
XP_ASSERT( strVersion <= CUR_STREAM_VERS );
|
||||
result = sqlite3_blob_write( blob, &strVersion, sizeof(strVersion), 0 );
|
||||
result = sqlite3_blob_write( blob, &strVersion, sizeof(strVersion), 0/*offset*/ );
|
||||
assertPrintResult( pDb, result, SQLITE_OK );
|
||||
const XP_U8* ptr = stream_getPtr( stream );
|
||||
result = sqlite3_blob_write( blob, ptr, len, sizeof(strVersion) );
|
||||
result = sqlite3_blob_write( blob, data, len, sizeof(strVersion) /* offset */ );
|
||||
assertPrintResult( pDb, result, SQLITE_OK );
|
||||
result = sqlite3_blob_close( blob );
|
||||
assertPrintResult( pDb, result, SQLITE_OK );
|
||||
|
@ -127,13 +125,24 @@ writeBlobColumn( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 curRow,
|
|||
sqlite3_finalize( stmt );
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%lld", curRow );
|
||||
return curRow;
|
||||
}
|
||||
|
||||
static sqlite3_int64
|
||||
writeBlobColumnStream( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 curRow,
|
||||
const char* column )
|
||||
{
|
||||
XP_U16 strVersion = stream_getVersion( stream );
|
||||
const XP_U8* data = stream_getPtr( stream );
|
||||
gsize len = stream_getSize( stream );
|
||||
return writeBlobColumnData( data, len, strVersion, pDb, curRow, column );
|
||||
}
|
||||
|
||||
sqlite3_int64
|
||||
writeNewGameToDB( XWStreamCtxt* stream, sqlite3* pDb )
|
||||
{
|
||||
sqlite3_int64 newRow = writeBlobColumn( stream, pDb, -1, "game" );
|
||||
sqlite3_int64 newRow = writeBlobColumnStream( stream, pDb, -1, "game" );
|
||||
return newRow;
|
||||
}
|
||||
|
||||
|
@ -145,7 +154,7 @@ writeToDB( XWStreamCtxt* stream, void* closure )
|
|||
sqlite3* pDb = cGlobals->pDb;
|
||||
|
||||
XP_Bool newGame = -1 == selRow;
|
||||
selRow = writeBlobColumn( stream, pDb, selRow, "game" );
|
||||
selRow = writeBlobColumnStream( stream, pDb, selRow, "game" );
|
||||
|
||||
if ( newGame ) { /* new row; need to insert blob first */
|
||||
cGlobals->selRow = selRow;
|
||||
|
@ -154,6 +163,29 @@ writeToDB( XWStreamCtxt* stream, void* closure )
|
|||
(*cGlobals->onSave)( cGlobals->onSaveClosure, selRow, newGame );
|
||||
}
|
||||
|
||||
static void
|
||||
addSnap( sqlite3* pDb, sqlite3_int64 curRow )
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
char* filename = "./red.png";
|
||||
GError *error = NULL;
|
||||
GdkPixbuf* snap = gdk_pixbuf_new_from_file_at_size( filename, 80, 80, &error );
|
||||
XP_ASSERT( !!snap );
|
||||
|
||||
gchar* buffer;
|
||||
gsize buffer_size;
|
||||
gboolean worked = gdk_pixbuf_save_to_buffer( snap, &buffer, &buffer_size,
|
||||
"png", &error, NULL );
|
||||
XP_ASSERT( worked );
|
||||
sqlite3_int64 newRow = writeBlobColumnData( (const XP_U8*)buffer, buffer_size,
|
||||
CUR_STREAM_VERS, pDb, curRow, "snap" );
|
||||
XP_ASSERT( curRow == newRow );
|
||||
|
||||
g_free( buffer );
|
||||
g_object_unref( snap );
|
||||
}
|
||||
|
||||
void
|
||||
summarize( CommonGlobals* cGlobals )
|
||||
{
|
||||
|
@ -222,6 +254,8 @@ summarize( CommonGlobals* cGlobals )
|
|||
}
|
||||
sqlite3_finalize( stmt );
|
||||
XP_USE( result );
|
||||
|
||||
addSnap( cGlobals->pDb, cGlobals->selRow );
|
||||
}
|
||||
|
||||
GSList*
|
||||
|
@ -262,7 +296,7 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib )
|
|||
{
|
||||
XP_Bool success = XP_FALSE;
|
||||
const char* fmt = "SELECT room, ended, turn, nmoves, ntotal, nmissing, "
|
||||
"seed, connvia, gameid, lastMoveTime "
|
||||
"seed, connvia, gameid, lastMoveTime, snap "
|
||||
"FROM games WHERE rowid = %lld";
|
||||
XP_UCHAR query[256];
|
||||
snprintf( query, sizeof(query), fmt, rowid );
|
||||
|
@ -284,8 +318,27 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib )
|
|||
gib->gameID = sqlite3_column_int( ppStmt, 8 );
|
||||
gib->lastMoveTime = sqlite3_column_int( ppStmt, 9 );
|
||||
snprintf( gib->name, sizeof(gib->name), "Game %lld", rowid );
|
||||
|
||||
/* Load the snapshot */
|
||||
const XP_U8* ptr = sqlite3_column_blob( ppStmt, 10 );
|
||||
int size = sqlite3_column_bytes( ppStmt, 10 );
|
||||
/* Skip the version that's written in */
|
||||
ptr += sizeof(XP_U16); size -= sizeof(XP_U16);
|
||||
GInputStream* istr = g_memory_input_stream_new_from_data( ptr, size, NULL );
|
||||
GError *error = NULL;
|
||||
GdkPixbuf* snap = gdk_pixbuf_new_from_stream( istr, NULL, &error );
|
||||
g_object_unref( istr );
|
||||
|
||||
if ( !snap ) {
|
||||
XP_LOGF( "%s(): error from gdk_pixbuf_new_from_stream(): %s",
|
||||
__func__, error->message );
|
||||
g_error_free( error );
|
||||
}
|
||||
XP_ASSERT( !!snap );
|
||||
gib->snap = snap;
|
||||
}
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -354,7 +407,7 @@ loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid )
|
|||
void
|
||||
saveInviteAddrs( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid )
|
||||
{
|
||||
sqlite3_int64 row = writeBlobColumn( stream, pDb, rowid, "inviteInfo" );
|
||||
sqlite3_int64 row = writeBlobColumnStream( stream, pDb, rowid, "inviteInfo" );
|
||||
assert( row == rowid );
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef struct _GameInfo {
|
|||
XP_UCHAR name[128];
|
||||
XP_UCHAR room[128];
|
||||
XP_UCHAR conn[128];
|
||||
GdkPixbuf* snap;
|
||||
XP_U32 gameID;
|
||||
XP_S16 nMoves;
|
||||
XP_Bool gameOver;
|
||||
|
|
|
@ -75,8 +75,9 @@ findOpenGame( const GtkAppGlobals* apg, sqlite3_int64 rowid )
|
|||
return result;
|
||||
}
|
||||
|
||||
enum { ROW_ITEM, NAME_ITEM, ROOM_ITEM, GAMEID_ITEM, SEED_ITEM, CONN_ITEM, OVER_ITEM, TURN_ITEM,
|
||||
NMOVES_ITEM, NTOTAL_ITEM, MISSING_ITEM, LASTTURN_ITEM, N_ITEMS };
|
||||
enum { ROW_ITEM, ROW_THUMB, NAME_ITEM, ROOM_ITEM, GAMEID_ITEM, SEED_ITEM,
|
||||
CONN_ITEM, OVER_ITEM, TURN_ITEM, NMOVES_ITEM, NTOTAL_ITEM, MISSING_ITEM,
|
||||
LASTTURN_ITEM, N_ITEMS };
|
||||
|
||||
static void
|
||||
foreachProc( GtkTreeModel* model, GtkTreePath* XP_UNUSED(path),
|
||||
|
@ -143,12 +144,23 @@ addTextColumn( GtkWidget* list, const gchar* title, int item )
|
|||
gtk_tree_view_append_column( GTK_TREE_VIEW(list), column );
|
||||
}
|
||||
|
||||
static void
|
||||
addImageColumn( GtkWidget* list, const gchar* title, int item )
|
||||
{
|
||||
GtkCellRenderer* renderer = gtk_cell_renderer_pixbuf_new();
|
||||
GtkTreeViewColumn* column =
|
||||
gtk_tree_view_column_new_with_attributes( title, renderer,
|
||||
"pixbuf", item, NULL );
|
||||
gtk_tree_view_append_column( GTK_TREE_VIEW(list), column );
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
init_games_list( GtkAppGlobals* apg )
|
||||
{
|
||||
GtkWidget* list = gtk_tree_view_new();
|
||||
|
||||
addTextColumn( list, "Row", ROW_ITEM );
|
||||
addImageColumn( list, "Snap", ROW_THUMB );
|
||||
addTextColumn( list, "Name", NAME_ITEM );
|
||||
addTextColumn( list, "Room", ROOM_ITEM );
|
||||
addTextColumn( list, "GameID", GAMEID_ITEM );
|
||||
|
@ -163,6 +175,7 @@ init_games_list( GtkAppGlobals* apg )
|
|||
|
||||
GtkListStore* store = gtk_list_store_new( N_ITEMS,
|
||||
G_TYPE_INT64, /* ROW_ITEM */
|
||||
GDK_TYPE_PIXBUF,/* ROW_THUMB */
|
||||
G_TYPE_STRING, /* NAME_ITEM */
|
||||
G_TYPE_STRING, /* ROOM_ITEM */
|
||||
G_TYPE_INT, /* GAMEID_ITEM */
|
||||
|
@ -212,6 +225,7 @@ add_to_list( GtkWidget* list, sqlite3_int64 rowid, XP_Bool isNew,
|
|||
}
|
||||
gtk_list_store_set( store, &iter,
|
||||
ROW_ITEM, rowid,
|
||||
ROW_THUMB, gib->snap,
|
||||
NAME_ITEM, gib->name,
|
||||
ROOM_ITEM, gib->room,
|
||||
GAMEID_ITEM, gib->gameID,
|
||||
|
@ -385,6 +399,7 @@ handle_delete_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
|||
} else {
|
||||
XP_LOGF( "%s: not calling relaycon_deleted: no relayID", __func__ );
|
||||
}
|
||||
g_object_unref( gib.snap );
|
||||
}
|
||||
apg->selRows = g_array_set_size( apg->selRows, 0 );
|
||||
updateButtons( apg );
|
||||
|
@ -531,6 +546,7 @@ onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew )
|
|||
GameInfo gib;
|
||||
if ( getGameInfo( apg->params->pDb, rowid, &gib ) ) {
|
||||
add_to_list( apg->listWidget, rowid, isNew, &gib );
|
||||
g_object_unref( gib.snap );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
BIN
xwords4/linux/red.png
Normal file
BIN
xwords4/linux/red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 B |
Loading…
Reference in a new issue