#include <phantasmal/lpc_names.h> #include <phantasmal/log.h> #include <kernel/user.h> inherit USER_STATE; private mapping text; private int is_clone; private int active; static void create(varargs int clone) { ::create(); is_clone = clone; if(clone) { /* Not the current state (yet) */ active = 0; } else { text = ([ ]); } } static void pop_state(void) { user->notify_done_scrolling(); ::pop_state(); } string get_text(void) { if(previous_program() != US_SCROLL_TEXT) error("Only scrollstates can call get_text!"); if(is_clone) return nil; return text[previous_object()]; } void set_text(string newtext) { if(previous_program() != US_SCROLL_TEXT) error("Only scrollstates can call set_text!"); if(is_clone) error("Can't set text of a clone!"); text[previous_object()] = newtext; } void append_text(string newtext) { string tmp; if(previous_program() != US_SCROLL_TEXT) error("Only scrollstates can call append_text!"); tmp = text[previous_object()]; if(!tmp) tmp = ""; tmp += newtext; text[previous_object()] = tmp; } static void scroll_page(void) { mixed* lines, *firstlines; string text; int num_lines; text = call_other(US_SCROLL_TEXT, "get_text"); if(!text) { LOGD->write_syslog("No text found in US_SCROLL_TEXT:scroll_page!", LOG_ERROR); return; } lines = explode("\n" + text + "\n", "\n"); num_lines = user->get_num_lines() - 1; /* -1 for status line */ if(num_lines >= sizeof(lines)) { send_string(text); call_other(US_SCROLL_TEXT, "set_text", nil); pop_state(); return; } firstlines = lines[..(num_lines-1)]; lines = lines[num_lines..]; text = implode(lines, "\n"); call_other(US_SCROLL_TEXT, "set_text", text); text = implode(firstlines, "\r\n") + "\r\n"; send_string(text); /* Print prompt at bottom */ send_string("*** (enter to scroll forward, q to quit) ***\r\n"); } /* USER_STATE functions */ void add_text(string str) { call_other(US_SCROLL_TEXT, "append_text", str); } int from_user(string input) { if(!input) return MODE_ECHO; input = STRINGD->trim_whitespace(input); if(input == "") { scroll_page(); return MODE_ECHO; } if(input == "q" || input == "quit") { call_other(US_SCROLL_TEXT, "set_text", nil); pop_state(); return MODE_ECHO; } send_string("*** Don't recognize command: " + input + "\r\n"); return MODE_ECHO; } void to_user(string output) { call_other(US_SCROLL_TEXT, "append_text", output); if(!active) scroll_page(); } void switch_to(int pushp) { string tmp; active = 1; /* If we pop back to an empty SCROLL_TEXT state, get rid of it */ tmp = call_other(US_SCROLL_TEXT, "get_text"); if(!tmp || tmp == "") { pop_state(); return; } scroll_page(); } void switch_from(int popp) { active = 0; /* call_other(US_SCROLL_TEXT, "set_text", nil); */ }