Created Def.LogDisplay for displaying messages in a log. Changed error reporting layer to use Def.LogDisplay. Changed engine error reporting to not clip errors to a single line.
This commit is contained in:
@@ -1824,6 +1824,7 @@
|
||||
<Function name='Flush'/>
|
||||
<Function name='GetThreadVariable'/>
|
||||
<Function name='ReadFile'/>
|
||||
<Function name='ReportScriptError'/>
|
||||
<Function name='RunWithThreadVariables'/>
|
||||
<Function name='Trace'/>
|
||||
<Function name='Warn'/>
|
||||
|
||||
@@ -749,6 +749,10 @@ save yourself some time, copy this for undocumented things:
|
||||
Tries to read the file at <code>sPath</code>. If successful, it returns the file's contents.
|
||||
If unsuccessful, it returns two values: <code>nil</code> and <code>"error"</code>.
|
||||
</Function>
|
||||
<Function name='ReportScriptError' return='' arguments= 'string error, string error_type'>
|
||||
Reports the error through the error reporting system. error_type is the type used for the dialog that is presented, a dialog will not appear for a type the user has chosen to ignore.<br/>
|
||||
error is optional an defaults to "Script error occurred.". error_type is optional and defaults to "LUA_ERROR".
|
||||
</Function>
|
||||
<Function name='RunWithThreadVariables' return='int' arguments='function func, table t, ...'>
|
||||
Calls <code>func(...)</code> with two LuaThreadVariables set, and returns the return values of <code>func()</code>.
|
||||
</Function>
|
||||
|
||||
@@ -26,6 +26,7 @@ GrooveRadar
|
||||
HelpDisplay
|
||||
HoldJudgment
|
||||
InputList
|
||||
LogDisplay
|
||||
MemoryCardDisplay
|
||||
MeterDisplay
|
||||
Model
|
||||
@@ -43,4 +44,4 @@ Sprite
|
||||
StepsDisplay
|
||||
StepsDisplayList
|
||||
TextBanner
|
||||
WorkoutGraph
|
||||
WorkoutGraph
|
||||
|
||||
@@ -1,56 +1,9 @@
|
||||
-- If you are a common themer, DO NOT INCLUDE THIS FILE IN YOUR THEME.
|
||||
-- This layer is purely for error reporting, so that you can see errors on screen easily while running stepmania.
|
||||
-- If you include this file in your theme, you will not benefit from any improvements in error reporting.
|
||||
-- If you want a different background behind the errors, then include "ScreenSystemLayer errorbg.lua" in your theme.
|
||||
-- If you want to adjust how long errors stay on screen for, call the "SetErrorMessageTime" function. (see usage notes in comments above that function)
|
||||
|
||||
-- Minor text formatting functions from Kyzentun.
|
||||
-- TODO: Figure out why BitmapText:maxwidth doesn't do what I want.
|
||||
local function width_limit_text(text, limit, natural_zoom)
|
||||
natural_zoom= natural_zoom or 1
|
||||
if text:GetWidth() * natural_zoom > limit then
|
||||
text:zoomx(limit / text:GetWidth())
|
||||
else
|
||||
text:zoomx(natural_zoom)
|
||||
end
|
||||
end
|
||||
|
||||
local function width_clip_text(text, limit)
|
||||
local full_text= text:GetText()
|
||||
local fits= text:GetZoomedWidth() <= limit
|
||||
local prev_max= #full_text - 1
|
||||
local prev_min= 0
|
||||
if not fits then
|
||||
while prev_max - prev_min > 1 do
|
||||
local new_max= math.round((prev_max + prev_min) / 2)
|
||||
text:settext(full_text:sub(1, 1+new_max))
|
||||
if text:GetZoomedWidth() <= limit then
|
||||
prev_min= new_max
|
||||
else
|
||||
prev_max= new_max
|
||||
end
|
||||
end
|
||||
text:settext(full_text:sub(1, 1+prev_min))
|
||||
end
|
||||
end
|
||||
|
||||
local function width_clip_limit_text(text, limit, natural_zoom)
|
||||
natural_zoom= natural_zoom or text:GetZoomY()
|
||||
local text_width= text:GetWidth() * natural_zoom
|
||||
if text_width > limit * 2 then
|
||||
text:zoomx(natural_zoom * .5)
|
||||
width_clip_text(text, limit)
|
||||
else
|
||||
width_limit_text(text, limit, natural_zoom)
|
||||
end
|
||||
end
|
||||
|
||||
local text_actors= {}
|
||||
local line_height= 12 -- A good line height for Common Normal at .5 zoom.
|
||||
local line_width= SCREEN_WIDTH - 20
|
||||
|
||||
local next_message_actor= 1
|
||||
local show_requested= false
|
||||
|
||||
local min_message_time= {show= 1, hide= .03125}
|
||||
local default_message_time= {show= 4, hide= .125}
|
||||
@@ -92,130 +45,12 @@ function GetErrorMessageTimeDefault(which)
|
||||
return default_message_time[which]
|
||||
end
|
||||
|
||||
local frame_args= {
|
||||
Name="Error frame",
|
||||
InitCommand= function(self)
|
||||
self:y(-SCREEN_HEIGHT)
|
||||
end,
|
||||
ScriptErrorMessageCommand = function(self, params)
|
||||
show_requested= false
|
||||
self:stoptweening()
|
||||
self:visible(true)
|
||||
local covered_height= math.min(line_height * next_message_actor, SCREEN_HEIGHT)
|
||||
self:y(-SCREEN_HEIGHT + covered_height)
|
||||
self:sleep(message_time.show)
|
||||
self:queuecommand("DecNextActor")
|
||||
-- Shift the text on all the actors being shown up by one.
|
||||
for i= next_message_actor, 1, -1 do
|
||||
if text_actors[i] then
|
||||
text_actors[i]:visible(true)
|
||||
if i > 1 and text_actors[i-1] then
|
||||
text_actors[i]:settext(text_actors[i-1]:GetText())
|
||||
else
|
||||
-- Someone long ago decided that it was a good idea for "::" to be
|
||||
-- a synonym for "\n", so that strings in metrics could have line
|
||||
-- breaks.
|
||||
-- So replace "::" with ":" so we don't have unwanted line breaks.
|
||||
text_actors[i]:settext(params.Message:gsub("::", ":"))
|
||||
end
|
||||
width_clip_limit_text(text_actors[i], line_width)
|
||||
end
|
||||
end
|
||||
if next_message_actor <= #text_actors then
|
||||
next_message_actor= next_message_actor + 1
|
||||
end
|
||||
end,
|
||||
ToggleErrorsMessageCommand= function(self, params)
|
||||
if show_requested then
|
||||
self:playcommand("HideErrors")
|
||||
else
|
||||
self:playcommand("ShowErrors")
|
||||
end
|
||||
end,
|
||||
ShowErrorsMessageCommand= function(self, params)
|
||||
show_requested= true
|
||||
for i, mactor in ipairs(text_actors) do
|
||||
if mactor:GetText() ~= "" then
|
||||
mactor:visible(true)
|
||||
next_message_actor= next_message_actor + 1
|
||||
end
|
||||
end
|
||||
next_message_actor= next_message_actor - 1
|
||||
local covered_height= math.min(line_height * next_message_actor, SCREEN_HEIGHT)
|
||||
self:stoptweening()
|
||||
self:visible(true)
|
||||
self:linear(message_time.hide)
|
||||
self:y(-SCREEN_HEIGHT + covered_height)
|
||||
end,
|
||||
HideErrorsMessageCommand= function(self, params)
|
||||
if not show_requested then return end
|
||||
show_requested= false
|
||||
self:stoptweening()
|
||||
next_message_actor= 1
|
||||
self:linear(message_time.hide)
|
||||
self:y(-SCREEN_HEIGHT)
|
||||
self:queuecommand("HideText")
|
||||
end,
|
||||
ClearErrorsMessageCommand= function(self, params)
|
||||
-- This is so that someone using ShowErrorsMessageCommand can clear ones
|
||||
-- they've dealt with.
|
||||
-- Only allow clearing errors that we have scrolled off screen.
|
||||
for i, mactor in ipairs(text_actors) do
|
||||
if not mactor:GetVisible() then
|
||||
mactor:settext("")
|
||||
end
|
||||
end
|
||||
end,
|
||||
DecNextActorCommand= function(self)
|
||||
self:linear(message_time.hide)
|
||||
self:y(self:GetY()-line_height)
|
||||
if text_actors[next_message_actor] then
|
||||
text_actors[next_message_actor]:visible(false)
|
||||
end
|
||||
next_message_actor= next_message_actor - 1
|
||||
if next_message_actor > 1 then
|
||||
self:queuecommand("DecNextActor")
|
||||
else
|
||||
self:queuecommand("Off")
|
||||
end
|
||||
end,
|
||||
HideTextCommand= function(self)
|
||||
for i, mactor in ipairs(text_actors) do
|
||||
mactor:visible(false)
|
||||
end
|
||||
end,
|
||||
OffCommand= cmd(visible,false),
|
||||
Def.Quad {
|
||||
Name= "errorbg",
|
||||
InitCommand= function(self)
|
||||
self:setsize(SCREEN_WIDTH, SCREEN_HEIGHT)
|
||||
self:horizalign(left)
|
||||
self:vertalign(top)
|
||||
self:diffuse(color("0,0,0,0"))
|
||||
self:diffusealpha(.85)
|
||||
end,
|
||||
}
|
||||
local log_args= {
|
||||
Name= "ScriptError",
|
||||
ReplaceLinesWhenHidden= true,
|
||||
Times= message_time,
|
||||
}
|
||||
-- Create enough text actors that we can fill the screen.
|
||||
local num_text= SCREEN_HEIGHT / line_height
|
||||
for i= 1, num_text do
|
||||
frame_args[#frame_args+1]= LoadFont("Common","Normal") .. {
|
||||
Name="Text" .. i,
|
||||
InitCommand= function(self)
|
||||
-- Put them in the list in reverse order so the ones at the bottom of the screen are used first.
|
||||
text_actors[num_text-i+1]= self
|
||||
self:horizalign(left)
|
||||
self:vertalign(top)
|
||||
self:x(SCREEN_LEFT + 10)
|
||||
self:y(SCREEN_TOP + (line_height * (i-1)) + 2)
|
||||
self:shadowlength(1)
|
||||
self:zoom(.5)
|
||||
self:visible(false)
|
||||
end,
|
||||
OffCommand= cmd(visible,false),
|
||||
}
|
||||
end
|
||||
|
||||
Trace("Loaded error layer.")
|
||||
|
||||
return Def.ActorFrame(frame_args)
|
||||
return Def.LogDisplay(log_args)
|
||||
|
||||
@@ -371,6 +371,78 @@ function IsUsingWideScreen()
|
||||
end;
|
||||
end;
|
||||
|
||||
-- Minor text formatting functions from Kyzentun.
|
||||
-- TODO: Figure out why BitmapText:maxwidth doesn't do what I want.
|
||||
-- Intentionally undocumented because they should be moved to BitmapText ASAP
|
||||
function width_limit_text(text, limit, natural_zoom)
|
||||
natural_zoom= natural_zoom or 1
|
||||
if text:GetWidth() * natural_zoom > limit then
|
||||
text:zoomx(limit / text:GetWidth())
|
||||
else
|
||||
text:zoomx(natural_zoom)
|
||||
end
|
||||
end
|
||||
|
||||
function width_clip_text(text, limit)
|
||||
local full_text= text:GetText()
|
||||
local fits= text:GetZoomedWidth() <= limit
|
||||
local prev_max= #full_text - 1
|
||||
local prev_min= 0
|
||||
if not fits then
|
||||
while prev_max - prev_min > 1 do
|
||||
local new_max= math.round((prev_max + prev_min) / 2)
|
||||
text:settext(full_text:sub(1, 1+new_max))
|
||||
if text:GetZoomedWidth() <= limit then
|
||||
prev_min= new_max
|
||||
else
|
||||
prev_max= new_max
|
||||
end
|
||||
end
|
||||
text:settext(full_text:sub(1, 1+prev_min))
|
||||
end
|
||||
end
|
||||
|
||||
function width_clip_limit_text(text, limit, natural_zoom)
|
||||
natural_zoom= natural_zoom or text:GetZoomY()
|
||||
local text_width= text:GetWidth() * natural_zoom
|
||||
if text_width > limit * 2 then
|
||||
text:zoomx(natural_zoom * .5)
|
||||
width_clip_text(text, limit)
|
||||
else
|
||||
width_limit_text(text, limit, natural_zoom)
|
||||
end
|
||||
end
|
||||
|
||||
function convert_text_to_indented_lines(text, indent, width, text_zoom)
|
||||
local text_as_lines= split("\n", text:GetText())
|
||||
local indented_lines= {}
|
||||
for i, line in ipairs(text_as_lines) do
|
||||
local remain= line
|
||||
local sub_lines= 0
|
||||
repeat
|
||||
text:settext(remain)
|
||||
local clipped= false
|
||||
local indent_mult= 0
|
||||
if i > 1 then
|
||||
indent_mult= indent_mult + 1
|
||||
end
|
||||
if sub_lines > 0 then
|
||||
indent_mult= 2
|
||||
end
|
||||
local usable_width= width - (indent * indent_mult)
|
||||
if text:GetWidth() * text_zoom > usable_width * 2 then
|
||||
clipped= true
|
||||
width_clip_text(text, usable_width * 2)
|
||||
end
|
||||
indented_lines[#indented_lines+1]= {
|
||||
indent_mult, text:GetText()}
|
||||
remain= remain:sub(#text:GetText()+1)
|
||||
sub_lines= sub_lines + 1
|
||||
until not clipped
|
||||
end
|
||||
return indented_lines
|
||||
end
|
||||
|
||||
-- (c) 2005-2011 Glenn Maynard, Chris Danford, SSC
|
||||
-- All rights reserved.
|
||||
--
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
-- This is a little fake actor class meant for displaying lines of a log.
|
||||
-- It's placed inside Def, but it's actually just an ActorFrame with some
|
||||
-- children and special commands.
|
||||
|
||||
-- LogDisplay listens for several messages that control its behavior.
|
||||
-- The name given to the LogDisplay is added to the name of the message to
|
||||
-- make the messages unique to this LogDisplay. So to issue a command to
|
||||
-- the LogDisplay, broadcast the message "<command><name>".
|
||||
-- For a LogDisplay named "Foo", you would broadcase "Foo" to add to the
|
||||
-- log, "ToggleFoo" to toggle whether it's shown or hidden, and so on.
|
||||
|
||||
-- Some of the control messages take tables of args.
|
||||
-- Arg elements of the form "name= type" are named, and must be a value of
|
||||
-- the given type.
|
||||
-- Arg elements of the form "name" are unnamed.
|
||||
|
||||
-- The messages are:
|
||||
-- <name>: params= {message= string, dont_show= bool}
|
||||
-- Adds message to the log to be shown when revealing.
|
||||
-- If dont_show is false, then Show will be automatically executed with
|
||||
-- auto_hide= true.
|
||||
-- Messages with line breaks will take up multiple lines.
|
||||
-- The newest message in the log has index 1.
|
||||
-- Toggle: No params
|
||||
-- Executes either Show or Hide, depending on the current state.
|
||||
-- Show: params= {range= {last_message, lines}, auto_hide= bool}
|
||||
-- Shows the messages currently in the log.
|
||||
-- range[1] is the index of the last message to show.
|
||||
-- range[2] is the max number of lines to show.
|
||||
-- range[1] defaults to a cleavage shot.
|
||||
-- range[2] defaults to MaxDisplayLines.
|
||||
-- If auto_hide is non-nil, Hide will be execuated after a short time.
|
||||
-- If auto_hide is a number, it will be used as the time to wait before
|
||||
-- hiding. Otherwise, the Times.show will be used.
|
||||
-- Query: No params
|
||||
-- Broadcasts "<name>Response" message with a table containing:
|
||||
-- {log_len= number, hidden= bool}
|
||||
-- log_len is the number of messages currently in the log.
|
||||
-- hidden is whether the LogDisplay is currently hidden.
|
||||
-- Hide: No params
|
||||
-- Hides the LogDisplay.
|
||||
-- Clear: params= {messages}
|
||||
-- Clears the messages in the log. If messages is a number, only clears
|
||||
-- that many messages, oldest first.
|
||||
|
||||
-- params to Def.LogDisplay():
|
||||
-- {
|
||||
-- Name= string
|
||||
-- The name will be used as the name of the main ActorFrame and to
|
||||
-- control what messages the LogDisplay listens for.
|
||||
-- MaxLogLen= number
|
||||
-- The maximum number of messages to store in the log.
|
||||
-- MaxDisplayLines= number
|
||||
-- The maximum number of lines that can be displayed at a time.
|
||||
-- ReplaceLinesWhenHidden= bool
|
||||
-- If this is true, any messages recieved while the LogDisplay is hidden
|
||||
-- will replace the message currently at the front of the log.
|
||||
-- If this is false, messages recieved while the LogDisplay is hidden
|
||||
-- will push other messages back. Messages pushed past MaxLines will be
|
||||
-- removed.
|
||||
-- Font= font name
|
||||
-- The name of the font to use. This will be passed to THEME:GetPathF,
|
||||
-- so it should not be a path.
|
||||
-- LineHeight= number
|
||||
-- The height in pixels to use between lines.
|
||||
-- LineWidth= number
|
||||
-- The width that lines should be limited to.
|
||||
-- TextZoom= number
|
||||
-- The zoom factor to apply to the text.
|
||||
-- TextColor= color
|
||||
-- The color to use for the text.
|
||||
-- Times= {show= number, hide= number}
|
||||
-- show is the amount of time to wait before automatically hiding when
|
||||
-- Show is executed with AutoHide == true. It's passed as a table, so
|
||||
-- if you keep a copy of the table, you should be able to modify it to
|
||||
-- change the time.
|
||||
-- hide is used as the time for the default hide command to hide.
|
||||
-- Indent= number
|
||||
-- The amount in pixels to indent lines that were part of a multi-line
|
||||
-- message.
|
||||
-- Hide= function(self)
|
||||
-- This command will be executed when the LogDisplay needs to be hidden.
|
||||
-- Hide will also be executed during the InitCommand, so the
|
||||
-- LogDisplay will start in the hidden state.
|
||||
-- Show= function(self, Lines)
|
||||
-- This command will be executed when the LogDisplay needs to be shown.
|
||||
-- Lines is the number of lines to show.
|
||||
-- }
|
||||
-- Any actors placed in params will be used and drawn behind the text.
|
||||
-- If there are no actors in params, a quad filling the area will be used.
|
||||
-- Reasonable defaults are provided for everything except Name. If Name is
|
||||
-- blank, you get nothing. Defaults assume the LogDisplay should fill the
|
||||
-- screen when in use.
|
||||
|
||||
-- Below is the implementation of the above features.
|
||||
|
||||
local log_display_mt= {
|
||||
__index= {
|
||||
create_actors= function(self, params)
|
||||
self.name= params.Name
|
||||
self.font= params.Font or "Common Normal"
|
||||
self.line_height= params.LineHeight or 12
|
||||
self.line_width= params.LineWidth or SCREEN_WIDTH
|
||||
self.text_zoom= params.TextZoom or .5
|
||||
self.text_color= params.TextColor or color("#93a1a1")
|
||||
self.max_lines= params.MaxLines or SCREEN_HEIGHT / self.line_height
|
||||
self.max_log= params.MaxLogLen or self.max_lines
|
||||
self.indent= params.Indent or 8
|
||||
self.times= params.Times
|
||||
self.param_hide= params.Hide or
|
||||
function(subself)
|
||||
subself:linear(params.Times.hide)
|
||||
subself:y(-SCREEN_HEIGHT)
|
||||
end
|
||||
self.param_show= params.Show or
|
||||
function(subself, lines)
|
||||
subself:visible(true)
|
||||
subself:linear(params.Times.hide)
|
||||
local cover= math.min(self.line_height * (lines+.5), SCREEN_HEIGHT)
|
||||
subself:y(-SCREEN_HEIGHT + cover)
|
||||
end
|
||||
|
||||
self.text_actors= {}
|
||||
self.message_log= {}
|
||||
self.messes_since_update= 0
|
||||
|
||||
local name_mess= self.name .. "MessageCommand"
|
||||
local args= {
|
||||
Name= self.name,
|
||||
InitCommand= function(subself)
|
||||
self.container= subself; -- This semicolon ends this statement.
|
||||
-- Without it, the next would be ambiguous syntax.
|
||||
-- Let the InitCommand passed in params do something.
|
||||
(params.InitCommand or function() end)(subself)
|
||||
self:hide()
|
||||
end,
|
||||
OffCommand= function(subself)
|
||||
subself:visible(false)
|
||||
for i, actor in ipairs(self.text_actors) do
|
||||
actor:visible(false)
|
||||
end
|
||||
end,
|
||||
[name_mess]= function(subself, mess)
|
||||
if not mess.message then return end
|
||||
if self.messes_since_update > self.max_log then return end
|
||||
-- Long ago, someone decided that "::" should be an alias for "\n"
|
||||
-- and hardcoded it into BitmapText.
|
||||
local message= tostring(mess.message):gsub("::", ":")
|
||||
if params.ReplaceLinesWhenHidden and self.hidden then
|
||||
self:clear()
|
||||
self.message_log[1]= message
|
||||
else
|
||||
table.insert(self.message_log, 1, message)
|
||||
if #self.message_log > self.max_log then
|
||||
table.remove(self.message_log)
|
||||
end
|
||||
end
|
||||
if not mess.dont_show or not self.hidden then
|
||||
self.messes_since_update= self.messes_since_update + 1
|
||||
self.hidden= false
|
||||
subself:stoptweening()
|
||||
subself:queuecommand("Update")
|
||||
end
|
||||
end,
|
||||
["Toggle" .. name_mess]= function(subself)
|
||||
if self.hidden then
|
||||
self:show()
|
||||
else
|
||||
self:hide()
|
||||
end
|
||||
end,
|
||||
["Hide" .. name_mess]= function(subself)
|
||||
self:hide()
|
||||
end,
|
||||
["Show" .. name_mess]= function(subself, mess)
|
||||
self:show(mess.range, mess.auto_hide)
|
||||
end,
|
||||
["Clear" .. name_mess]= function(subself, mess)
|
||||
self:clear(mess[1])
|
||||
end,
|
||||
UpdateCommand= function(subself)
|
||||
self:show(nil, true)
|
||||
self.messes_since_update= 0
|
||||
end,
|
||||
LoadFont(self.font) ..
|
||||
{
|
||||
Name="WidthTester",
|
||||
InitCommand= function(subself)
|
||||
self.width_tester= subself
|
||||
subself:zoom(self.text_zoom)
|
||||
subself:visible(false)
|
||||
end
|
||||
}
|
||||
}
|
||||
if #params == 0 then
|
||||
args[#args+1]= Def.Quad {
|
||||
Name= "Logbg",
|
||||
InitCommand= function(subself)
|
||||
subself:setsize(self.line_width, self.line_height*self.max_lines)
|
||||
subself:horizalign(left)
|
||||
subself:vertalign(top)
|
||||
subself:diffuse(color("#002b36"))
|
||||
subself:diffusealpha(.85)
|
||||
end,
|
||||
}
|
||||
else
|
||||
-- Add bg actors passed through params.
|
||||
for i, actor in ipairs(params) do
|
||||
args[#args+1]= actor
|
||||
end
|
||||
end
|
||||
-- Add commands passed through params.
|
||||
for name, command in pairs(params) do
|
||||
if type(name) == "string" and name:find("Command") and not args[name] then
|
||||
args[name]= command
|
||||
end
|
||||
end
|
||||
for i= 1, self.max_lines do
|
||||
args[#args+1]= LoadFont(self.font) ..
|
||||
{
|
||||
Name="Text" .. i,
|
||||
InitCommand= function(subself)
|
||||
-- Put them in the list in reverse order so the ones at the
|
||||
-- bottom of the screen are used first.
|
||||
self.text_actors[self.max_lines-i+1]= subself
|
||||
subself:horizalign(left)
|
||||
subself:vertalign(top)
|
||||
subself:y(self.line_height * (i-1))
|
||||
subself:zoom(self.text_zoom)
|
||||
subself:diffuse(self.text_color)
|
||||
subself:visible(false)
|
||||
end,
|
||||
OffCommand= cmd(visible,false),
|
||||
}
|
||||
end
|
||||
return Def.ActorFrame(args)
|
||||
end,
|
||||
hide= function(self)
|
||||
self.container:stoptweening()
|
||||
self.param_hide(self.container)
|
||||
self.container:queuecommand("Off")
|
||||
self.hidden= true
|
||||
end,
|
||||
show= function(self, range, auto_hide)
|
||||
if not range then range= {} end
|
||||
local start= range[1] or 1
|
||||
local lmax= range[2] or self.max_lines
|
||||
local indented_lines= {}
|
||||
local next_message= start
|
||||
local num_lines= 0
|
||||
while num_lines < lmax and self.message_log[next_message] do
|
||||
self.width_tester:settext(self.message_log[next_message])
|
||||
local lines_to_add= convert_text_to_indented_lines(
|
||||
self.width_tester, self.indent, self.line_width, self.text_zoom)
|
||||
indented_lines[#indented_lines+1]= lines_to_add
|
||||
num_lines= num_lines + #lines_to_add
|
||||
next_message= next_message + 1
|
||||
end
|
||||
local use_next= 1
|
||||
local used= 0
|
||||
for i, mess in ipairs(indented_lines) do
|
||||
for l, line in ipairs(mess) do
|
||||
-- Start at the end of the mess because the text actors are in
|
||||
-- reverse order.
|
||||
local ind= use_next + (#mess - l)
|
||||
local actor= self.text_actors[ind]
|
||||
if actor and used <= lmax then
|
||||
actor:settext(line[2])
|
||||
local indent= 8 + self.indent * line[1]
|
||||
local lw= self.line_width - (indent + 8)
|
||||
width_limit_text(actor, lw, self.text_zoom)
|
||||
actor:x(indent)
|
||||
actor:visible(true)
|
||||
used= used + 1
|
||||
end
|
||||
end
|
||||
use_next= use_next + #mess
|
||||
end
|
||||
self.container:stoptweening()
|
||||
self.param_show(self.container, used)
|
||||
self.hidden= false
|
||||
if auto_hide then
|
||||
self.container:sleep(self.times.show)
|
||||
self.container:queuecommand("Hide" .. self.name)
|
||||
end
|
||||
end,
|
||||
clear= function(self, messes)
|
||||
if #self.message_log < 1 then return end
|
||||
if not messes then
|
||||
self.message_log= {}
|
||||
else
|
||||
for i= 1, messes do
|
||||
table.remove(self.message_log)
|
||||
if #self.message_log < 1 then break end
|
||||
end
|
||||
end
|
||||
end
|
||||
}}
|
||||
|
||||
function Def.LogDisplay(params)
|
||||
if type(params.Name) ~= "string" or params.Name == "" then
|
||||
ReportScriptError("Cannot create a LogDisplay without a name.")
|
||||
return nil
|
||||
end
|
||||
|
||||
if not params.Times then params.Times= {show= 4, hide= .125} end
|
||||
if not params.Times.show then params.Times.show= 4 end
|
||||
if not params.Times.hide then params.Times.hide= .125 end
|
||||
|
||||
local new_log_display= setmetatable({}, log_display_mt)
|
||||
_G[params.Name .. "LogDisplay"]= new_log_display
|
||||
return new_log_display:create_actors(params)
|
||||
end
|
||||
+19
-12
@@ -794,27 +794,17 @@ bool LuaHelpers::LoadScript( Lua *L, const RString &sScript, const RString &sNam
|
||||
void LuaHelpers::ScriptErrorMessage(RString const& Error)
|
||||
{
|
||||
Message msg("ScriptError");
|
||||
msg.SetParam("Message", Error);
|
||||
msg.SetParam("message", Error);
|
||||
MESSAGEMAN->Broadcast(msg);
|
||||
}
|
||||
|
||||
Dialog::Result LuaHelpers::ReportScriptError(RString const& Error, RString ErrorType, bool UseAbort)
|
||||
{
|
||||
size_t line_break_pos= Error.find('\n');
|
||||
RString short_error;
|
||||
if(line_break_pos == RString::npos)
|
||||
{
|
||||
short_error= Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
short_error= Error.substr(0, line_break_pos);
|
||||
}
|
||||
// Protect from a recursion loop resulting from a mistake in the error reporting lua.
|
||||
if(!InReportScriptError)
|
||||
{
|
||||
InReportScriptError= true;
|
||||
ScriptErrorMessage(short_error);
|
||||
ScriptErrorMessage(Error);
|
||||
InReportScriptError= false;
|
||||
}
|
||||
LOG->Warn(Error.c_str());
|
||||
@@ -1154,6 +1144,22 @@ namespace
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ReportScriptError(lua_State* L)
|
||||
{
|
||||
RString error= "Script error occurred.";
|
||||
RString error_type= "LUA_ERROR";
|
||||
if(lua_isstring(L, 1))
|
||||
{
|
||||
error= SArg(1);
|
||||
}
|
||||
if(lua_isstring(L, 2))
|
||||
{
|
||||
error_type= SArg(2);
|
||||
}
|
||||
LuaHelpers::ReportScriptError(error, error_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg luaTable[] =
|
||||
{
|
||||
LIST_METHOD( Trace ),
|
||||
@@ -1163,6 +1169,7 @@ namespace
|
||||
LIST_METHOD( ReadFile ),
|
||||
LIST_METHOD( RunWithThreadVariables ),
|
||||
LIST_METHOD( GetThreadVariable ),
|
||||
LIST_METHOD( ReportScriptError ),
|
||||
{ NULL, NULL }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1054,7 +1054,7 @@ class DebugLineToggleErrors : public IDebugLine
|
||||
virtual RString GetPageName() const { return "Theme"; }
|
||||
virtual void DoAndLog( RString &sMessageOut )
|
||||
{
|
||||
Message msg("ToggleErrors");
|
||||
Message msg("ToggleScriptError");
|
||||
MESSAGEMAN->Broadcast(msg);
|
||||
IDebugLine::DoAndLog(sMessageOut);
|
||||
}
|
||||
@@ -1068,7 +1068,7 @@ class DebugLineClearErrors : public IDebugLine
|
||||
virtual RString GetPageName() const { return "Theme"; }
|
||||
virtual void DoAndLog( RString &sMessageOut )
|
||||
{
|
||||
Message msg("ClearErrors");
|
||||
Message msg("ClearScriptError");
|
||||
MESSAGEMAN->Broadcast(msg);
|
||||
IDebugLine::DoAndLog(sMessageOut);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user