Add listeners to model so board can be notified whenever dictionary

changes.  Pass dict into draw via new API, removing it from the
draw_begin calls.
This commit is contained in:
ehouse 2008-09-05 12:11:37 +00:00
parent 9be9842e48
commit 181e880d8d
14 changed files with 115 additions and 42 deletions

View file

@ -79,6 +79,9 @@ static void boardCellChanged( void* board, XP_U16 turn, XP_U16 col,
XP_U16 row, XP_Bool added );
static void boardTilesChanged( void* board, XP_U16 turn, XP_S16 index1,
XP_S16 index2 );
static void dictChanged( void* p_board, const DictionaryCtxt* oldDict,
const DictionaryCtxt* newDict );
static void boardTurnChanged( void* board );
static void boardGameOver( void* board );
static void setArrow( BoardCtxt* board, XP_U16 row, XP_U16 col );
@ -155,6 +158,7 @@ board_make( MPFORMAL ModelCtxt* model, ServerCtxt* server, DrawCtx* draw,
/* could just pass in invalCell.... PENDING(eeh) */
model_setBoardListener( model, boardCellChanged, result );
model_setTrayListener( model, boardTilesChanged, result );
model_setDictListener( model, dictChanged, result );
server_setTurnChangeListener( server, boardTurnChanged, result );
server_setGameOverListener( server, boardGameOver, result );
@ -1421,11 +1425,11 @@ board_requestHint( BoardCtxt* board,
const XP_U16 selPlayer = board->selPlayer;
PerTurnInfo* pti = board->selInfo;
EngineCtxt* engine = server_getEngineFor( board->server, selPlayer );
result = !!engine && preflight( board );
const TrayTileSet* tileSet;
ModelCtxt* model = board->model;
result = !!engine && preflight( board );
/* undo any current move. otherwise we won't pass the full tray to
the engine. Would it be better, though, to pass the whole tray
regardless where its contents are? */
@ -1568,7 +1572,7 @@ coordToCell( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_U16* colP, XP_U16* rowP )
} /* coordToCell */
XP_Bool
getCellRect( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Rect* rect )
getCellRect( const BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Rect* rect )
{
XP_S16 top;
XP_Bool onBoard = XP_TRUE;
@ -2870,6 +2874,17 @@ boardTilesChanged( void* p_board, XP_U16 turn, XP_S16 index1, XP_S16 index2 )
}
} /* boardTilesChanged */
static void
dictChanged( void* p_board, const DictionaryCtxt* oldDict,
const DictionaryCtxt* newDict )
{
BoardCtxt* board = (BoardCtxt*)p_board;
XP_ASSERT( !!board->draw );
if ( NULL == oldDict || !dict_tilesAreSame( oldDict, newDict ) ) {
draw_dictChanged( board->draw, newDict );
}
}
static void
boardTurnChanged( void* p_board )
{

View file

@ -231,7 +231,6 @@ drawBoard( BoardCtxt* board )
{
if ( board->needsDrawing
&& draw_boardBegin( board->draw,
model_getDictionary( board->model ),
&board->boardBounds,
dfsFor( board, OBJ_BOARD ) ) ) {

View file

@ -246,7 +246,7 @@ void invalTrayTilesBetween( BoardCtxt* board, XP_U16 tileIndex1,
XP_U16 tileIndex2 );
void makeMiniWindowForText( BoardCtxt* board, const XP_UCHAR* text,
MiniWindowType winType );
XP_Bool getCellRect( BoardCtxt* board, XP_U16 col, XP_U16 row,
XP_Bool getCellRect( const BoardCtxt* board, XP_U16 col, XP_U16 row,
XP_Rect* rect);
void getDragCellRect( BoardCtxt* board, XP_U16 col, XP_U16 row,
XP_Rect* rectP );

View file

@ -208,7 +208,7 @@ dict_tilesAreSame( const DictionaryCtxt* dict1, const DictionaryCtxt* dict2 )
} /* dict_tilesAreSame */
void
dict_writeToStream( DictionaryCtxt* dict, XWStreamCtxt* stream )
dict_writeToStream( const DictionaryCtxt* dict, XWStreamCtxt* stream )
{
XP_U16 maxCount = 0;
XP_U16 maxValue = 0;

View file

@ -146,7 +146,7 @@ XP_Bitmap dict_getFaceBitmap( const DictionaryCtxt* dict, Tile tile,
XP_LangCode dict_getLangCode( const DictionaryCtxt* dict );
#endif
void dict_writeToStream( DictionaryCtxt* ctxt, XWStreamCtxt* stream );
void dict_writeToStream( const DictionaryCtxt* ctxt, XWStreamCtxt* stream );
void dict_loadFromStream( DictionaryCtxt* dict, XWStreamCtxt* stream );

View file

@ -109,8 +109,10 @@ typedef struct DrawCtxVTable {
void DRAW_VTABLE_NAME(destroyCtxt) ( DrawCtx* dctx );
void DRAW_VTABLE_NAME(dictChanged)( DrawCtx* dctx,
const DictionaryCtxt* dict );
XP_Bool DRAW_VTABLE_NAME(boardBegin) ( DrawCtx* dctx,
const DictionaryCtxt* dict,
const XP_Rect* rect,
DrawFocusState dfs );
void DRAW_VTABLE_NAME(objFinished)( DrawCtx* dctx, BoardObjectType typ,
@ -244,7 +246,8 @@ struct DrawCtx {
#endif
#define draw_destroyCtxt(dc) CALL_DRAW_NAME0(destroyCtxt, dc)
#define draw_boardBegin( dc,d,r,f ) CALL_DRAW_NAME3(boardBegin, dc, d,r,f)
#define draw_dictChanged( dc, d ) CALL_DRAW_NAME1(dictChanged, (dc), (d))
#define draw_boardBegin( dc,r,f ) CALL_DRAW_NAME2(boardBegin, dc, r,f)
#define draw_objFinished( dc, t, r, d ) CALL_DRAW_NAME3(objFinished, (dc), (t), (r), (d))
#define draw_trayBegin( dc, r, o, f ) CALL_DRAW_NAME3(trayBegin,dc, r, o, f)
#define draw_vertScrollBoard( dc, r, d, f ) \

View file

@ -50,6 +50,9 @@ static void notifyBoardListeners( ModelCtxt* model, XP_U16 turn,
XP_U16 col, XP_U16 row, XP_Bool added );
static void notifyTrayListeners( ModelCtxt* model, XP_U16 turn,
XP_S16 index1, XP_S16 index2 );
static void notifyDictListeners( ModelCtxt* model, DictionaryCtxt* oldDict,
DictionaryCtxt* newDict );
static CellTile getModelTileRaw( const ModelCtxt* model, XP_U16 col,
XP_U16 row );
static void setModelTileRaw( ModelCtxt* model, XP_U16 col, XP_U16 row,
@ -265,13 +268,16 @@ model_setNPlayers( ModelCtxt* model, XP_U16 nPlayers )
void
model_setDictionary( ModelCtxt* model, DictionaryCtxt* dict )
{
model->vol.dict = dict;
DictionaryCtxt* oldDict = model->vol.dict;
model->vol.dict = dict;
if ( !!dict ) {
XP_U16 nFaces = dict_numTileFaces( dict );
XP_ASSERT( !!model->vol.stack );
stack_setBitsPerTile( model->vol.stack, nFaces <= 32? 5 : 6 );
}
if ( !!dict ) {
XP_U16 nFaces = dict_numTileFaces( dict );
XP_ASSERT( !!model->vol.stack );
stack_setBitsPerTile( model->vol.stack, nFaces <= 32? 5 : 6 );
notifyDictListeners( model, oldDict, dict );
}
} /* model_setDictionary */
DictionaryCtxt*
@ -1407,6 +1413,13 @@ model_setTrayListener( ModelCtxt* model, TrayListener tl, void* data )
model->vol.trayListenerData = data;
} /* model_setBoardListener */
void
model_setDictListener( ModelCtxt* model, DictListener dl, void* data )
{
model->vol.dictListenerFunc = dl;
model->vol.dictListenerData = data;
} /* model_setBoardListener */
static void
notifyBoardListeners( ModelCtxt* model, XP_U16 turn, XP_U16 col, XP_U16 row,
XP_Bool added )
@ -1427,6 +1440,17 @@ notifyTrayListeners( ModelCtxt* model, XP_U16 turn, XP_S16 index1,
}
} /* notifyTrayListeners */
static void
notifyDictListeners( ModelCtxt* model, DictionaryCtxt* oldDict,
DictionaryCtxt* newDict )
{
XP_ASSERT( !!newDict );
if ( model->vol.dictListenerFunc != NULL ) {
(*model->vol.dictListenerFunc)( model->vol.dictListenerData, oldDict,
newDict );
}
} /* notifyDictListeners */
static void
printString( XWStreamCtxt* stream, const XP_UCHAR* str )
{

View file

@ -192,6 +192,10 @@ typedef void (*TrayListener)( void* data, XP_U16 turn,
XP_S16 index1, XP_S16 index2 );
void model_setTrayListener( ModelCtxt* model, TrayListener bl,
void* data );
typedef void (*DictListener)( void* data, const DictionaryCtxt* oldDict,
const DictionaryCtxt* newDict );
void model_setDictListener( ModelCtxt* model, DictListener dl,
void* data );
void model_foreachPendingCell( ModelCtxt* model, XP_S16 turn,
BoardListener bl, void* data );
void model_foreachPrevCell( ModelCtxt* model, BoardListener bl, void* data );

View file

@ -51,6 +51,8 @@ typedef struct ModelVolatiles {
void* boardListenerData;
TrayListener trayListenerFunc;
void* trayListenerData;
DictListener dictListenerFunc;
void* dictListenerData;
MPSLOT
} ModelVolatiles;

View file

@ -85,9 +85,14 @@ curses_draw_destroyCtxt( DrawCtx* XP_UNUSED(p_dctx) )
// CursesDrawCtx* dctx = (CursesDrawCtx*)p_dctx;
} /* draw_setup */
static void
curses_draw_dictChanged( DrawCtx* XP_UNUSED(p_dctx),
const DictionaryCtxt* XP_UNUSED(dict) )
{
}
static XP_Bool
curses_draw_boardBegin( DrawCtx* XP_UNUSED(p_dctx),
const DictionaryCtxt* XP_UNUSED(dict),
const XP_Rect* XP_UNUSED(rect),
DrawFocusState XP_UNUSED(dfs) )
{
@ -526,6 +531,7 @@ cursesDrawCtxtMake( WINDOW* boardWin )
}
SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, curses );
SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, curses );
SET_VTABLE_ENTRY( dctx->vtable, draw_boardBegin, curses );
SET_VTABLE_ENTRY( dctx->vtable, draw_objFinished, curses );
SET_VTABLE_ENTRY( dctx->vtable, draw_trayBegin, curses );

View file

@ -309,9 +309,15 @@ gtk_draw_destroyCtxt( DrawCtx* p_dctx )
} /* gtk_draw_destroyCtxt */
static void
gtk_draw_dictChanged( DrawCtx* XP_UNUSED(p_dctx),
const DictionaryCtxt* XP_UNUSED(dict) )
{
}
static XP_Bool
gtk_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* XP_UNUSED(dict),
const XP_Rect* rect, DrawFocusState XP_UNUSED(dfs) )
gtk_draw_boardBegin( DrawCtx* p_dctx, const XP_Rect* rect,
DrawFocusState XP_UNUSED(dfs) )
{
GdkRectangle gdkrect;
GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx;
@ -1069,11 +1075,9 @@ gtkDrawCtxtMake( GtkWidget* drawing_area, GtkAppGlobals* globals )
SET_VTABLE_ENTRY( dctx->vtable, draw_drawMiniWindow, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, gtk );
#endif
/* SET_VTABLE_ENTRY( dctx, draw_frameBoard, gtk_ ); */
/* SET_VTABLE_ENTRY( dctx, draw_frameTray, gtk_ ); */
dctx->pangoContext = gtk_widget_get_pango_context( drawing_area );
dctx->drawing_area = drawing_area;
dctx->globals = globals;

View file

@ -245,8 +245,8 @@ checkFontOffsets( PalmDrawCtx* dctx, const DictionaryCtxt* dict )
}
static XP_Bool
palm_common_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* dict,
const XP_Rect* rect, DrawFocusState dfs )
palm_common_draw_boardBegin( DrawCtx* p_dctx, const XP_Rect* rect,
DrawFocusState dfs )
{
PalmDrawCtx* dctx = (PalmDrawCtx*)p_dctx;
PalmAppGlobals* globals = dctx->globals;
@ -254,8 +254,6 @@ palm_common_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* dict,
WinDrawRectangleFrame(rectangleFrame, (RectangleType*)rect);
}
checkFontOffsets( dctx, dict );
#ifdef DRAW_FOCUS_FRAME
dctx->topFocus = dfs == DFS_TOP;
#endif
@ -264,8 +262,8 @@ palm_common_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* dict,
#ifdef COLOR_SUPPORT
static XP_Bool
palm_clr_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* dict,
const XP_Rect* rect, DrawFocusState dfs )
palm_clr_draw_boardBegin( DrawCtx* p_dctx, const XP_Rect* rect,
DrawFocusState dfs )
{
PalmDrawCtx* dctx = (PalmDrawCtx*)p_dctx;
@ -277,7 +275,7 @@ palm_clr_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* dict,
HIGHRES_PUSH_NOPOP(dctx);
palm_common_draw_boardBegin( p_dctx, dict, rect, dfs );
palm_common_draw_boardBegin( p_dctx, rect, dfs );
return XP_TRUE;
} /* palm_clr_draw_boardBegin */
@ -592,6 +590,25 @@ palm_common_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect,
return complete;
} /* palm_common_draw_drawCell */
void
palm_draw_destroyCtxt( DrawCtx* p_dctx )
{
PalmDrawCtx* dctx = (PalmDrawCtx*)p_dctx;
XP_FREE( dctx->mpool, p_dctx->vtable );
if ( !!dctx->fontHtInfo ) {
XP_FREE( dctx->mpool, dctx->fontHtInfo );
}
XP_FREE( dctx->mpool, dctx );
} /* palm_draw_destroyCtxt */
static void
palm_draw_dictChanged( DrawCtx* p_dctx, const DictionaryCtxt* dict )
{
checkFontOffsets( (PalmDrawCtx*)p_dctx, dict );
}
static void
palm_draw_invertCell( DrawCtx* p_dctx, const XP_Rect* rect )
{
@ -1464,8 +1481,10 @@ palm_drawctxt_make( MPFORMAL GraphicsAbility able,
vtable call. so....*/
dctx->drawBitmapFunc = drawBitmapAt;
SET_VTABLE_ENTRY( dctx->vtable, draw_invertCell, palm );
SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, palm );
SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, palm );
SET_VTABLE_ENTRY( dctx->vtable, draw_invertCell, palm );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTile, palm );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTileBack, palm );
#ifdef POINTER_SUPPORT
@ -1533,14 +1552,3 @@ palm_drawctxt_make( MPFORMAL GraphicsAbility able,
return (DrawCtx*)dctx;
} /* palm_drawctxt_make */
void
palm_drawctxt_destroy( DrawCtx* p_dctx )
{
PalmDrawCtx* dctx = (PalmDrawCtx*)p_dctx;
XP_FREE( dctx->mpool, p_dctx->vtable );
if ( !!dctx->fontHtInfo ) {
XP_FREE( dctx->mpool, dctx->fontHtInfo );
}
XP_FREE( dctx->mpool, dctx );
} /* palm_drawctxt_destroy */

View file

@ -1315,7 +1315,7 @@ stopApplication( PalmAppGlobals* globals )
}
if ( !!globals->draw ) {
palm_drawctxt_destroy( globals->draw );
draw_destroyCtxt( globals->draw );
}
game_dispose( &globals->game );

View file

@ -58,6 +58,7 @@ struct CEDrawCtx {
HWND mainWin;
CEAppGlobals* globals;
const DictionaryCtxt* dict;
COLORREF prevBkColor;
@ -509,7 +510,6 @@ drawTextLines( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* text, XP_S16 padding,
DLSTATIC XP_Bool
DRAW_FUNC_NAME(boardBegin)( DrawCtx* p_dctx,
const DictionaryCtxt* XP_UNUSED(dict),
const XP_Rect* XP_UNUSED(rect),
DrawFocusState dfs )
{
@ -1369,6 +1369,13 @@ DRAW_FUNC_NAME(destroyCtxt)( DrawCtx* p_dctx )
XP_FREE( dctx->mpool, dctx );
} /* ce_draw_destroyCtxt */
DLSTATIC void
DRAW_FUNC_NAME(dictChanged)( DrawCtx* p_dctx, const DictionaryCtxt* dict )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
dctx->dict = dict;
}
#ifdef DRAW_LINK_DIRECT
DLSTATIC XP_Bool
DRAW_FUNC_NAME(vertScrollBoard)( DrawCtx* p_dctx, XP_Rect* rect,
@ -1475,6 +1482,7 @@ ce_drawctxt_make( MPFORMAL HWND mainWin, CEAppGlobals* globals )
}
SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_boardBegin, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawCell, ce );