Debug Log Window
Module — 2 files
These files compile together (same module folder).
file_1.verse
GDebugLog<public> := module:
<#
Created by Gorosuke
Version: 1.1.0
Don't rename these modules
モジュール名の変更はしないでください
#>
using { /Verse.org/Assets }
using { /Verse.org/Colors }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { Categories }
using { Data }
using { Devices }
using { Internal }
using { Functions }
using { Widgets }
using { WidgetInternal }
Devices<public> := module:
debug_log_device<public> := class(creative_device):
@editable
DebugMode<private>:debug_mode = debug_mode.Development
@editable
ShowButton:button_device = button_device{}
@editable
MaxLog:?int = option{100}
var DebugLogWindow<private>:[player]debug_log_widget = map{}
OnBegin<override>()<suspends>:void=
set GetDebugData().DebugMode = DebugMode
set GetDebugData().MaxLog = MaxLog
if(DebugMode <> debug_mode.Release):
ShowButton.InteractedWithEvent.Subscribe(OnInteractShow)
Show<public><final>(InPlayer:player):void=
if(not DebugLogWindow[InPlayer]):
NewWindow := MakeDebugLogWidget(InPlayer)
NewWindow.Show()
if(set DebugLogWindow[InPlayer] = NewWindow):
spawn{AwaitUIClose(NewWindow)}
Hide<public><final>(InPlayer:player):void=
if(Window := DebugLogWindow[InPlayer]):
Window.Hide()
set DebugLogWindow = DebugLogWindow.RemoveKey(InPlayer)
ShowAll<public><final>():void=
for(PlayerElement : GetPlayspace().GetPlayers()):
Show(PlayerElement)
HideAll<public><final>():void=
for(PlayerElement : GetPlayspace().GetPlayers()):
Hide(PlayerElement)
RegisterWindow<public><final>(InWindow:debug_log_window):void=
return
AwaitUIClose<private>(InWidget:debug_log_widget)<suspends>:void=
InWidget.ClosedEvent.Await()
set DebugLogWindow = DebugLogWindow.RemoveKey(InWidget.Player)
OnInteractShow(Agent:agent):void=
if(Player := player[Agent]):
Show(Player)
DeviceCommandInput<public> := module:
input_info<internal> := class<concrete>:
@editable
InputTrigger<public>:input_trigger_device = input_trigger_device{}
@editable
ApplyHoldTime<public>:range_float = range_float{}
debug_log_device_command_input<public> := class(debug_log_device):
@editable
ShowInput:[]input_info = array{}
var TryAgents<private>:[]agent = array{}
OnBegin<override>()<suspends>:void=
(super:)OnBegin()
AwaitFirstInput()
AwaitFirstInput<private><final>()<suspends>:void=
if(FirstInput := ShowInput[0]):
loop:
FirstInputAgent := FirstInput.InputTrigger.PressedEvent.Await()
if(not TryAgents.Find[FirstInputAgent], Player := player[FirstInputAgent], GetDebugData().IsEnabledInputShow?):
set TryAgents += array{FirstInputAgent}
spawn{CheckInput(Player)}
CheckInput<private><final>(InPlayer:player)<suspends>:void=
defer:
set TryAgents = TryAgents.RemoveAllElements(InPlayer)
for(InputElement : ShowInput):
ReleasedInfo := AwaitTargetPlayerReleased(InPlayer, InputElement.InputTrigger)
Sleep(0.0)
if(not IsInRange[ReleasedInfo(1), InputElement.ApplyHoldTime]):
return
Self.Show(InPlayer)
AwaitTargetPlayerReleased<private><final>(InPlayer:player, InInputTrigger:input_trigger_device)<suspends>:tuple(player, float)=
loop:
ReleasedInfo := InInputTrigger.ReleasedEvent.Await()
if(ReleasedInfo(0) = InPlayer):
return (InPlayer, ReleasedInfo(1))
Categories<public> := module:
Normal<public>:category = category:
Prefix := option{"Normal"}
NameID := "Normal"
Color := NamedColors.LightSkyBlue
Warning<public>:category = category:
Prefix := option{"Warning"}
NameID := "Warning"
Color := NamedColors.Yellow
Error<public>:category = category:
Prefix := option{"Error"}
NameID := "Error"
Color := NamedColors.Red
category<public> := class<computes>:
# {Prefix} | {debug_log_data.Message} | {Suffix}で表記される。
Prefix<public>:?string = false
Suffix<public>:?string = false
# カテゴリの参照名を指定する。同名にすると同じカテゴリとして扱われる。
NameID<public>:string
Color<public>:color = NamedColors.White
Icon<public>:?texture = false
Data<public> := module:
debug_mode<public> := enum:
Development
Simulation
Release
MakeDebugLog<public><constructor>(InMessage:string, InCategory:category, ?InChannel:debug_mode=debug_mode.Development)<transacts> := debug_log:
Message := InMessage
Category := InCategory
Channel := InChannel
Date := GetSimulationElapsedTime()
MakeDebugLogAgent<public><constructor>(
InMessage:string, InCategory:category, InAgent:agent, ?InChannel:debug_mode=debug_mode.Development
)<transacts> := debug_log_agent:
MakeDebugLog<constructor>(InMessage, InCategory, ?InChannel:=InChannel)
Agent := InAgent
MakeDebugLogVector3<public><constructor>(
InMessage:string, InCategory:category, InVector3:vector3, ?InChannel:debug_mode=debug_mode.Development
)<transacts> := debug_log_vector3:
MakeDebugLog<constructor>(InMessage, InCategory, ?InChannel:=InChannel)
Vector3 := InVector3
debug_log<public> := class<computes><internal>:
Category<public>:category
Message<public>:string
Date<public>:float
Channel<public>:debug_mode
debug_log_agent<public> := class<internal>(debug_log):
Agent<public>:agent
debug_log_vector3<public> := class<internal>(debug_log):
Vector3<public>:vector3
ToString<public>(InData:debug_log)<computes><reads>:string=
Prefix :=
if(Value := InData.Category.Prefix?):
"{Value} | "
else:
""
Suffix :=
if(Value := InData.Category.Suffix?):
" | {Value}"
else:
""
"{Prefix}{InData.Message}{Suffix}"
Logger<public> := module:
NormalLog<public>(InMessage:string)<transacts>:void=
NewDebugLog := MakeDebugLog(InMessage, Categories.Normal)
PrintLog(NewDebugLog)
WarningLog<public>(InMessage:string)<transacts>:void=
NewDebugLog := MakeDebugLog(InMessage, Categories.Warning)
PrintLog(NewDebugLog)
ErrorLog<public>(InMessage:string)<transacts>:void=
NewDebugLog := MakeDebugLog(InMessage, Categories.Error)
PrintLog(NewDebugLog)
CategoryLog<public>(InMessage:string, InCategory:category)<transacts>:void=
NewDebugLog := MakeDebugLog(InMessage, InCategory)
PrintLog(NewDebugLog)
PrintLog<public>(InData:debug_log)<transacts>:void=
AddLog(InData)
if(IsDisplayable[InData.Channel]):
DebugMessage := "{InData}"
Print("{DebugMessage}", ?Color:=InData.Category.Color)
AddLog<public>(InData:debug_log)<transacts>:void=
set GetDebugData().DebugLogs += array{InData}
if:
MaxLength := GetDebugData().MaxLog?
GetDebugData().DebugLogs.Length > MaxLength
SlicedLogs := GetDebugData().DebugLogs.Slice[GetDebugData().DebugLogs.Length-MaxLength]
set GetDebugData().DebugLogs = SlicedLogs
Functions<public> := module:
GetAllLogs<public>()<transacts>:[]debug_log=
GetDebugData().DebugLogs
GetLogs<public>(InCategory:category)<transacts>:[]debug_log=
for(DataElemenet : GetDebugData().DebugLogs, DataElemenet.Category.NameID = InCategory.NameID):
DataElemenet
ClearLogs<public>()<transacts>:void=
set GetDebugData().DebugLogs = array{}
GetUsedCategories<public>()<transacts>:[]category=
var Result:[]category = array{}
for(DataElement : GetDebugData().DebugLogs):
if:
not (
for(ResultElement : Result, ResultElement.NameID = DataElement.Category.NameID):
ResultElement
)[0]
then:
set Result += array{DataElement.Category}
Result
SetDebugMode<public>(InMode:debug_mode)<transacts>:void=
set GetDebugData().DebugMode = InMode
Widgets<public> := module:
MakeDebugLogWidget<public><constructor>(InPlayer:player, ?InWindows:[]debug_log_window=array{})<transacts> := debug_log_widget:
Player := InPlayer
CustomWindows := InWindows
debug_log_window<public> := class<abstract><unique>:
Title<public><localizes>:message="Debug Log Window"
TitleButton<public><final>:text_button_base = button_loud{}
var<private> MyCanvas<public>:canvas = canvas{}
var<private> Layers<public>:[]canvas = array{}
Order<public>:int = 0
Create<public>():canvas=
CreateLayers()
SetLayer(0)
NewCanvas := CreateCanvas()
set MyCanvas = NewCanvas
NewCanvas
CreateCanvas<private>():canvas=
canvas:
Slots :=
for(LayerElement : Layers):
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.0, Y := 0.0}
Maximum := vector2{X := 1.0, Y := 1.0}
Widget := LayerElement
AddLayer<protected>(InLayer:canvas):void=
set Layers += array{InLayer}
SetLayer<public>(InIndex:int):void=
for(Index -> LayerElement : Layers):
if(Index = InIndex):
LayerElement.SetVisibility(widget_visibility.Visible)
else:
LayerElement.SetVisibility(widget_visibility.Collapsed)
CreateLayers<protected>():void
Update<public>():void=
return
SetEnabled<public>(IsEnabled:logic):void=
if(IsEnabled?):
MyCanvas.SetVisibility(widget_visibility.Visible)
else:
MyCanvas.SetVisibility(widget_visibility.Hidden)
AwaitEvents<public>()<suspends>:void=
Sleep(Inf)
WidgetLogHistory<public> := module:
MessageOpenButton<public><localizes>:message="Open"
MessageScrollUpButton<public><localizes>:message="↑"
MessageScrollDownButton<public><localizes>:message="↓"
# コンフィグウィンドウを作るまでの仮置き
MessageIsEnabledInputShowButton<public><localizes>:message="Input: Enabled"
MessageIsDisabledInputShowButton<public><localizes>:message="Input: Disabled"
card_sort_mode<internal> := enum:
Least
Oldest
ToString<internal>(InMode:card_sort_mode)<computes><reads>:string=
case(InMode):
card_sort_mode.Least=> "Least"
card_sort_mode.Oldest=> "Oldest"
ToSortMode<internal>:[int]card_sort_mode = map:
0 => card_sort_mode.Least
1 => card_sort_mode.Oldest
debug_log_card<internal> := class:
Background<public>:color_block
TextBackground<public>:color_block
IconOr<public>:color_block
Text<public>:text_button_base
TimeText<public>:text_block
TimeTextBackground<public>:color_block
OpenButton<public>:text_button_base
SetVisible<public>(IsVisible:logic):void=
if(IsVisible?):
Background.SetVisibility(widget_visibility.Visible)
TextBackground.SetVisibility(widget_visibility.Visible)
IconOr.SetVisibility(widget_visibility.Visible)
Text.SetVisibility(widget_visibility.Visible)
OpenButton.SetVisibility(widget_visibility.Visible)
TimeText.SetVisibility(widget_visibility.Visible)
TimeTextBackground.SetVisibility(widget_visibility.Visible)
else:
Background.SetVisibility(widget_visibility.Collapsed)
TextBackground.SetVisibility(widget_visibility.Collapsed)
IconOr.SetVisibility(widget_visibility.Collapsed)
Text.SetVisibility(widget_visibility.Collapsed)
OpenButton.SetVisibility(widget_visibility.Collapsed)
TimeText.SetVisibility(widget_visibility.Collapsed)
TimeTextBackground.SetVisibility(widget_visibility.Collapsed)
debug_log_detail<internal> := class:
Background<public>:color_block
Header<public>:color_block
CategoryTitle<public>:text_button_base
TrackedDate<public>:text_button_base
Message<public>:text_block
AgentName<public>:text_button_base
TeleportToButton<public>:text_button_base
CloseButton<public>:text_button_base
Update<public>(InLog:debug_log):void=
Header.SetColor(InLog.Category.Color)
CategoryTitle.SetText(StringToMessage("{InLog.Category.NameID}"))
TrackedDate.SetText(StringToMessage(ToMMSS(InLog.Date)))
Message.SetText(StringToMessage("{InLog.Message}"))
CategoryTitle.SetEnabled(false)
TrackedDate.SetEnabled(false)
if(AgentData := debug_log_agent[InLog]):
AgentName.SetVisibility(widget_visibility.Visible)
AgentName.SetText(AgentToMessage(AgentData.Agent))
else:
AgentName.SetVisibility(widget_visibility.Collapsed)
if(Vector3Data := debug_log_vector3[InLog]):
TeleportToButton.SetVisibility(widget_visibility.Visible)
TeleportToButton.SetText(StringToMessage("{Vector3Data.Vector3}"))
else:
TeleportToButton.SetVisibility(widget_visibility.Collapsed)
debug_log_window_history<public> := class(debug_log_window):
Title<override><localizes>:message="Log History"
var DebugLogCards<private>:[]debug_log_card = array{}
ScrollUpButton<private>:text_button_base = button_loud{DefaultText := MessageScrollUpButton}
ScrollDownButton<private>:text_button_base = button_loud{DefaultText := Message
Sign in to download module
Copy-paste each file above is always free.