// load_events.h - Don Yang (uguu.org) // // 05/26/11 #ifndef LOAD_EVENTS_H_ #define LOAD_EVENTS_H_ #include #include #include #include #include using namespace std; class AllEvents { public: // Raw events with adjusted timestamps struct Event { Event() : row(0), column(0), frame(0), timestamp(0), line(-1), size(0) {} // Most recent cursor event int row, column; // Cursor position (0-based) int frame; // Frame count since start of recording session int timestamp; // Uptime in seconds since start of recording session // Text snapshot event, only valid if line is positive int line; // Line number that is being snapshotted int size; // Number of lines in the file string text; // Contents of the snapshotted line (no newline at the end) }; typedef vector List; // Placeholders for output lines. // (in-use status, output slot number) typedef list > OutputSlots; // Compiled event struct CompiledEvent { // Timestamp of current event int timestamp; // Timestamp in seconds int frame; // Frame count within the current second (numerator) int max_frame; // Frame count within the current second (denominator) // How to interpret the current event enum EditType { CURSOR = 0, // No text change, move cursor only REPLACE, // Replace output line with text APPEND, // Append text to output line DELETE, // Delete output line SLOW_CURSOR // Move cursor, but use compatibility rendering mode }; EditType type; // CURSOR: unused. // REPLACE: text to replace output slot. // APPEND: text to be appended to output slot. // DELETE: unused. // SLOW_CURSOR: text up to and including the cursor character. string text; // CURSOR: unused. // REPLACE: output slot. // APPEND: output slot. // DELETE: output slot. // SLOW_CURSOR: reference slot for finding base text and row. OutputSlots::iterator output; // CURSOR: vertical cursor position. // REPLACE: unused. // APPEND: unused. // DELETE: unused. // SLOW_CURSOR: unused. int row; // CURSOR: horizontal cursor position (bytes). // REPLACE: unused. // APPEND: unused. // DELETE: unused. // SLOW_CURSOR: horizontal cursor position (bytes). int column; }; typedef list CompiledEventList; // Setup and cleanup AllEvents(); ~AllEvents(); // Load events from file. // // It's possible to call this function multiple times, the end // result is that new events will be appended to existing events. // However, it's preferred to concatenate all input files into one // file (or pipe) and just call Load() once, since delta-encoding // state is not preserved across calls. void Load(FILE *input); // Compress idle time in raw events so that no two frames are more // than the specified number of seconds apart (ignoring subsecond // differences). This should be called before CompileEvents. void CompressIdleTime(int max_idle_seconds); // Compile all events into a more animation friendly form void CompileEvents(); // Get number of output slots inline int GetSlotCount() const { return output_slots_.empty() ? 0 : output_slots_.back().second + 1; } // Accessors inline const List &events() const { return events_; } inline const Event &event(int index) const { return *(events_[index]); } inline const CompiledEventList &compiled_events() const { return compiled_events_; } inline int max_file_size() const { return max_file_size_; } private: class FullSnapshot; class PartialSnapshot; // Compute same second frame numerator/denominator pairs void GetRelativeFrames(vector > *frames) const; // Remove redundant event entries void OptimizeEvents(); List events_; CompiledEventList compiled_events_; OutputSlots output_slots_; int max_file_size_; }; #endif // LOAD_EVENTS_H_