282 lines
7 KiB
C++
282 lines
7 KiB
C++
/******************************************************************************/
|
|
/* UI<=>GAME MESSAGES *********************************************************/
|
|
/******************************************************************************/
|
|
|
|
#ifndef _H_LW_LIB_MESSAGES
|
|
#define _H_LW_LIB_MESSAGES
|
|
#include <lw/lib/Strings.hh>
|
|
#include <lw/lib/Types.hh>
|
|
namespace lw {
|
|
|
|
|
|
/*= VIEWS ====================================================================*/
|
|
|
|
/* Empty abstract class that serves as a base for game views */
|
|
class A_GameView
|
|
{
|
|
public:
|
|
virtual ~A_GameView( ) = 0;
|
|
};
|
|
M_ABSTRACT_POINTERS( GameView );
|
|
|
|
|
|
/* Abstract class for a view builder
|
|
*
|
|
* User interfaces need to access the game's data in order to display it. View
|
|
* builders provide a way to do that; they are passed to the game's main loop
|
|
* by the UI. Once set, they will be used to create and update view data.
|
|
*/
|
|
class A_ViewBuilder
|
|
{
|
|
public:
|
|
virtual ~A_ViewBuilder( ) = 0;
|
|
|
|
/* This method creates a view instance. It is called twice when the
|
|
* builder is installed, in order to create a "double buffer" - one
|
|
* view can be sent to the UI while the other is being updated.
|
|
*/
|
|
virtual OP_GameView createView( ) = 0;
|
|
|
|
/* This method is responsible for updating a view instance. */
|
|
virtual void updateView( OP_GameView view ) = 0;
|
|
};
|
|
M_ABSTRACT_POINTERS( ViewBuilder );
|
|
|
|
|
|
/*= GAME STATE ===============================================================*/
|
|
|
|
/* State of the main loop */
|
|
enum class E_GameState {
|
|
NO_GAME , // No game loaded
|
|
GAME_PAUSED , // Game is loaded but not running
|
|
GAME_SLOW , // Game is running at slow speed
|
|
GAME_NORMAL , // Game is running at normal speed
|
|
GAME_FAST // Game is running at high speed
|
|
};
|
|
M_LSHIFT_OP( T_StringBuilder , E_GameState );
|
|
|
|
|
|
/*= PROGRESS INFORMATION =====================================================*/
|
|
|
|
/* Progress information for long operations - part (main or sub) */
|
|
class T_ProgressInfoPart
|
|
{
|
|
private:
|
|
T_String text_;
|
|
uint32_t progress_;
|
|
uint32_t total_;
|
|
|
|
public:
|
|
T_ProgressInfoPart( ) = delete;
|
|
T_ProgressInfoPart( T_String text , uint32_t progress , uint32_t total ) noexcept;
|
|
T_ProgressInfoPart( T_ProgressInfoPart&& other ) noexcept;
|
|
T_ProgressInfoPart( T_ProgressInfoPart const& other );
|
|
|
|
T_String const& text( ) const noexcept;
|
|
uint32_t progress( ) const noexcept;
|
|
uint32_t total( ) const noexcept;
|
|
};
|
|
|
|
/* Progress information for long operations - main */
|
|
class T_ProgressInfo
|
|
{
|
|
private:
|
|
T_ProgressInfoPart main_;
|
|
T_Optional< T_ProgressInfoPart > sub_;
|
|
|
|
public:
|
|
T_ProgressInfo( ) = delete;
|
|
T_ProgressInfo( T_String text , uint32_t progress , uint32_t total ) noexcept;
|
|
explicit T_ProgressInfo( T_ProgressInfoPart main ) noexcept;
|
|
T_ProgressInfo( T_ProgressInfoPart main , T_ProgressInfoPart sub ) noexcept;
|
|
T_ProgressInfo( T_ProgressInfoPart main ,
|
|
T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept;
|
|
T_ProgressInfo( T_String text , uint32_t progress , uint32_t total ,
|
|
T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept;
|
|
T_ProgressInfo( T_ProgressInfo&& other ) noexcept;
|
|
T_ProgressInfo( T_ProgressInfo const& other ) = delete;
|
|
|
|
T_ProgressInfoPart const& main( ) const noexcept;
|
|
bool hasSub( ) const noexcept;
|
|
T_ProgressInfoPart const& sub( ) const;
|
|
};
|
|
M_CLASS_POINTERS( ProgressInfo );
|
|
|
|
|
|
/*= MESSAGES =================================================================*/
|
|
|
|
/* Types of messages sent by the UI to the game */
|
|
enum class E_GameUIMessage {
|
|
/* Create a new game
|
|
* Data: XXX
|
|
*/
|
|
NEW ,
|
|
/* Load an existing game
|
|
* Data: uint32_t - game identifier
|
|
*/
|
|
LOAD ,
|
|
/* Save the current game
|
|
* Data: none
|
|
*/
|
|
SAVE ,
|
|
/* Quit the current game
|
|
* Data: none
|
|
*/
|
|
STOP ,
|
|
/* Quit current game (if any) the exit the main loop
|
|
* Data: none
|
|
*/
|
|
QUIT ,
|
|
|
|
/* Abort the current operation
|
|
* Data: none
|
|
*/
|
|
ABORT ,
|
|
|
|
/* Delete a saved game
|
|
* Data: uint32_t - game identifier
|
|
*/
|
|
DELETE ,
|
|
/* Copy or rename a saved game
|
|
* Data: XXX
|
|
*/
|
|
COPY_OR_RENAME ,
|
|
|
|
/* Set the current game's speed
|
|
* Data: E_GameState (but NO_GAME will be ignored)
|
|
*/
|
|
SET_SPEED ,
|
|
/* Execute computation steps
|
|
* Data: XXX
|
|
*/
|
|
STEPS ,
|
|
/* Set a view builder
|
|
* Data: XXX
|
|
*/
|
|
SET_VIEW ,
|
|
/* Indicate that a view has been displayed
|
|
* Data: T_String - identifier of the view
|
|
*/
|
|
VIEW_DISPLAYED ,
|
|
/* Send a query to the game
|
|
* Data: XXX
|
|
*/
|
|
QUERY ,
|
|
/* Send a command to the game
|
|
* Data: XXX
|
|
*/
|
|
COMMAND
|
|
};
|
|
M_LSHIFT_OP( T_StringBuilder , E_GameUIMessage );
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/* Types of messages sent by the main loop to the UI */
|
|
enum class E_GameLoopMessage {
|
|
/* Main loop exiting
|
|
* Data: none
|
|
*/
|
|
TERMINATED ,
|
|
/* Progress information
|
|
* Data: T_ProgressInfo
|
|
*/
|
|
PROGRESS ,
|
|
/* Operation completed
|
|
* Data: none
|
|
*/
|
|
DONE ,
|
|
/* State changed
|
|
* Data: E_GameState
|
|
*/
|
|
STATE_CHANGED ,
|
|
/* Indicate that a view is available
|
|
* Data: XXX
|
|
*/
|
|
VIEW_AVAILABLE ,
|
|
/* Query response
|
|
* Data: XXX
|
|
*/
|
|
QUERY_RESPONSE ,
|
|
/* Command execution - success
|
|
* Data: none
|
|
*/
|
|
COMMAND_OK ,
|
|
/* Command execution - syntax error
|
|
* Data: XXX
|
|
*/
|
|
COMMAND_SYNTAX ,
|
|
/* Command execution - error
|
|
* Data: XXX
|
|
*/
|
|
COMMAND_ERROR ,
|
|
};
|
|
M_LSHIFT_OP( T_StringBuilder , E_GameLoopMessage );
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/* Types for message data */
|
|
using T_GameUIMessageData = T_Union<
|
|
uint32_t ,
|
|
T_String ,
|
|
E_GameState
|
|
>;
|
|
using T_GameLoopMessageData = T_Union<
|
|
T_ProgressInfo ,
|
|
E_GameState
|
|
>;
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/* Message direction */
|
|
enum class E_MessageDirection {
|
|
FROM_UI_TO_GAME ,
|
|
FROM_GAME_TO_UI
|
|
};
|
|
|
|
/* Message class template, can be used for both directions */
|
|
template<
|
|
E_MessageDirection Direction ,
|
|
typename EType = std::conditional_t<
|
|
Direction == E_MessageDirection::FROM_UI_TO_GAME ,
|
|
E_GameUIMessage , E_GameLoopMessage > ,
|
|
typename DType = std::conditional_t<
|
|
Direction == E_MessageDirection::FROM_UI_TO_GAME ,
|
|
T_GameUIMessageData , T_GameLoopMessageData >
|
|
>
|
|
class T_GameMessage
|
|
{
|
|
public:
|
|
using T_Type = EType;
|
|
using T_Data = DType;
|
|
|
|
private:
|
|
using T_Self_ = T_GameMessage< Direction >;
|
|
T_Optional< T_Type > type_;
|
|
T_Optional< T_Data > data_;
|
|
|
|
public:
|
|
constexpr T_GameMessage( ) noexcept;
|
|
constexpr T_GameMessage( T_Type type ) noexcept;
|
|
T_GameMessage( T_Type type , T_Data data ) noexcept;
|
|
T_GameMessage( T_Self_ const& ) = delete;
|
|
T_GameMessage( T_Self_&& other ) noexcept;
|
|
|
|
T_Self_& operator =( T_Self_ const& ) = delete;
|
|
T_Self_& operator =( T_Self_&& other ) noexcept;
|
|
|
|
constexpr bool hasMessage( ) const noexcept;
|
|
constexpr T_Type type( ) const noexcept;
|
|
|
|
template< typename T >
|
|
constexpr T const& data( ) const;
|
|
};
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
using T_UIMessage = T_GameMessage< E_MessageDirection::FROM_UI_TO_GAME >;
|
|
using T_LoopMessage = T_GameMessage< E_MessageDirection::FROM_GAME_TO_UI >;
|
|
|
|
|
|
} // namespace lw
|
|
#endif // _H_LW_LIB_MESSAGES
|
|
#include <lw/lib/inline/Messages.hh>
|