Module: environment-debugger Author: Jason Trenouth, Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Thread message log define sealed class () sealed slot thread-message-log-buffer :: ; sealed slot thread-message-log-stream :: ; end class ; define sealed method make (class == , #key project :: , thread :: false-or()) => (log :: ) project-thread-message-log(project, thread) | next-method() end method; define sealed method initialize (log :: , #key project :: , thread :: false-or()) => () let buffer = interactor-buffer-for-thread(project, thread); let stream :: = make(, interval: buffer, direction: #"output"); log.thread-message-log-buffer := buffer; log.thread-message-log-stream := stream; let logs = project-thread-message-logs(project); element(logs, thread) := log; end method initialize; define function project-thread-message-logs (project :: ) => (message-logs :: ) let properties = project.project-properties; get-property(properties, #"thread-message-logs", default: #f) | begin let logs = make(); put-property!(properties, #"thread-message-logs", logs); logs end end function project-thread-message-logs; define function project-thread-message-log (project :: , thread :: ) => (log :: false-or()) let logs = project-thread-message-logs(project); element(logs, thread, default: #f) end function project-thread-message-log; define function reset-project-thread-message-logs (project :: ) => () let logs = project-thread-message-logs(project); remove-all-keys!(logs); end function reset-project-thread-message-logs; /// Message printing /// NB If we get an application-wide message, broadcast it to all /// the threads. /// /// ---*** DEBUGGER: This may be a bit costly, but we're probably /// stopping because the user clicked on the stop button anyway. If it /// proves too expensive then we can invent a holding pen for /// broadcast messages that message logs grab the latest entries from /// when they update. define sealed method print-application-message (device == #f, project :: , thread == #f, message :: ) => () end method print-application-message; define sealed method print-application-message (device :: , project :: , thread == #f, message :: ) => () let application = project.project-application; let threads = if (application) application.application-threads else #[] end; for (thread :: in threads) print-application-message(device, project, thread, message) end for; end method print-application-message; define sealed method print-application-message (device == #"environment", project :: , thread :: , message :: ) => () let log :: = make(, project: project, thread: thread); let buffer :: = log.thread-message-log-buffer; let stream :: = log.thread-message-log-stream; let last-node = buffer-end-node(buffer); let prev-node = node-previous(last-node); let section = prev-node & node-section(prev-node); let line = select (section by instance?) => section-output-line(section);
=> section-end-line(section); otherwise => #f; end; if (line) stream-position(stream) := line-start(line); write(stream, message); new-line(stream); if (instance?(section, )) section-output-line(section) := bp-line(stream-position(stream)) end; redisplay-section(section, editor: $environment-editor) else debug-message("Ignoring application message: %s", message) end end method print-application-message; define sealed method print-application-message (device == #"console", project :: , thread :: , message :: ) => () let thread-prefix :: = if (thread) format-to-string("Thread %d", thread-index(project, thread)) else environment-object-display-name(project, project, #f) end if; debug-message("%s: %s\n", thread-prefix, message) end method print-application-message;