#ifndef TERMINAL_OVERLAY_HPP #define TERMINAL_OVERLAY_HPP #include "terminalframebuffer.hpp" #include "network.hpp" #include namespace Overlay { using namespace Terminal; using namespace Network; using namespace std; enum Validity { Pending, Correct, IncorrectOrExpired }; /* The individual elements of an overlay -- cursor movements and replaced cells */ class OverlayElement { public: uint64_t expiration_time; virtual void apply( Framebuffer &fb ) const = 0; virtual Validity get_validity( const Framebuffer & ) const; OverlayElement( uint64_t s_expiration_time ) : expiration_time( s_expiration_time ) {} virtual ~OverlayElement() {} }; class OverlayCell : public OverlayElement { public: int row, col; Cell replacement; OverlayCell( uint64_t expiration_time, int s_row, int s_col, int background_color ); void apply( Framebuffer &fb ) const; }; class ConditionalOverlayCell : public OverlayCell { public: Cell original_contents; Validity get_validity( const Framebuffer &fb ) const; ConditionalOverlayCell( uint64_t expiration_time, int s_row, int s_col, int background_color, Cell s_original_contents ) : OverlayCell( expiration_time, s_row, s_col, background_color ), original_contents( s_original_contents ) {} }; class CursorMove : public OverlayElement { public: int new_row, new_col; void apply( Framebuffer &fb ) const; CursorMove( uint64_t expiration_time, int s_new_row, int s_new_col ); }; class ConditionalCursorMove : public CursorMove { public: Validity get_validity( const Framebuffer &fb ) const; ConditionalCursorMove( uint64_t expiration_time, int s_new_row, int s_new_col ) : CursorMove( expiration_time, s_new_row, s_new_col ) {} }; /* the various overlays -- some predictive and some for local notifications */ class OverlayEngine { protected: list elements; public: void cull( const Framebuffer &fb ); virtual void apply( Framebuffer &fb ) const; void clear( void ); typename list::const_iterator begin( void ) { return elements.begin(); } typename list::const_iterator end( void ) { return elements.end(); } OverlayEngine() : elements() {} virtual ~OverlayEngine(); }; class NotificationEngine : public OverlayEngine { private: bool needs_render; uint64_t last_word; uint64_t last_render; wstring message; uint64_t message_expiration; public: void apply( Framebuffer &fb ) const; void set_notification_string( const wstring s_message ); void server_ping( uint64_t s_last_word ); void render_notification( void ); NotificationEngine(); }; class PredictionEngine : public OverlayEngine { public: void new_user_byte( char the_byte, const Framebuffer &fb, int prediction_len ); }; /* the overlay manager */ class OverlayManager { private: NotificationEngine notifications; PredictionEngine predictions; int prediction_score; void calculate_score( const Framebuffer &fb ); public: void apply( Framebuffer &fb ); NotificationEngine & get_notification_engine( void ) { return notifications; } PredictionEngine & get_prediction_engine( void ) { return predictions; } OverlayManager() : notifications(), predictions(), prediction_score( 0 ) {} int wait_time( void ); }; } #endif