Skip to content

Commit 833ba96

Browse files
committed
refactor(YimActions): refactor history
- Change play history into a self-contained struct rather than a raw table. - Add navigable tips in the main YimActions UI.
1 parent ba47815 commit 833ba96

23 files changed

Lines changed: 460 additions & 182 deletions

SSV2/includes/classes/Mutex.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ function Mutex.new()
2929
return setmetatable({ m_locked = false }, Mutex)
3030
end
3131

32+
---@return boolean
33+
function Mutex:IsLocked()
34+
return self.m_locked
35+
end
36+
3237
function Mutex:Acquire()
3338
while (self.m_locked) do
3439
yield()

SSV2/includes/features/YimActionsV3.lua

Lines changed: 7 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ local CompanionManager = require("includes.services.CompanionManager")
1212
local t_AnimList = require("includes.data.actions.animations")
1313
local t_PedScenarios = require("includes.data.actions.scenarios")
1414
local Action = require("includes.structs.Action")
15+
local ActionsHistory = require("includes.structs.ActionsHistory")
1516
local Weapons = require("includes.data.weapons")
1617
local COL_YELLOW <const> = Color("yellow")
1718

@@ -21,11 +22,6 @@ local COL_YELLOW <const> = Color("yellow")
2122
--- | "scenes"
2223
--- | "clipsets"
2324

24-
---@alias ActionHistorySortMode
25-
---| 0 Timestamp
26-
---| 1 Type
27-
---| 2 Label
28-
2925
---@class YimActionsFavorites
3026
---@field anims table<string, AnimData>
3127
---@field scenarios table<string, ScenarioData>
@@ -45,8 +41,7 @@ local COL_YELLOW <const> = Color("yellow")
4541
---@field public Commands table<string, ActionCommandData>
4642
---@field public DrawNewCommandWindow boolean
4743
---@field public CurrentlyPlaying table<handle, Action>
48-
---@field public LastPlayed { count: integer, sort_mode: ActionHistorySortMode, data: array<{ action: Action, timestamp: seconds, type: eActionType, fmt: string }> }
49-
---@field private m_history_lookup set<string>
44+
---@field public LastPlayed ActionsHistory
5045
---@field public CompanionManager CompanionManager
5146
local YimActions = {}
5247
YimActions.__index = YimActions
@@ -60,13 +55,8 @@ function YimActions:init()
6055
self.DrawNewCommandWindow = false
6156
self.CompanionManager = CompanionManager.new()
6257
self.SceneManager = SceneManager.new()
58+
self.LastPlayed = ActionsHistory.new()
6359
self.CurrentlyPlaying = {}
64-
self.m_history_lookup = {}
65-
self.LastPlayed = {
66-
data = {},
67-
count = 0,
68-
sort_mode = 0,
69-
}
7060
self.Commands = {}
7161
self.m_file_names = {
7262
favorites = "saved_actions.json",
@@ -103,81 +93,21 @@ end
10393
function YimActions:UpdatePlayHistory(ped)
10494
local current = self.CurrentlyPlaying[self:GetPed(ped)]
10595
if (not current) then return end
106-
107-
local label = current.data.label
108-
local lookupArray = self.m_history_lookup
109-
if (lookupArray[label]) then return end
110-
111-
local type = current.action_type
112-
local fmt = _F("[%s] %s", current:TypeAsString(), label)
113-
local epoch = DateTime:Now():Epoch()
114-
table.insert(self.LastPlayed.data, {
115-
action = current,
116-
timestamp = epoch,
117-
type = type,
118-
fmt = fmt,
119-
})
120-
121-
lookupArray[label] = true
122-
self.LastPlayed.count = #self.LastPlayed.data
123-
self:SortPlayHistory()
96+
self.LastPlayed:Push(current)
12497
end
12598

12699
---@param index integer
127100
function YimActions:RemoveFromHistory(index)
128-
local data = self.LastPlayed.data
129-
local count = #data
130-
if (count == 0) then return end
131-
132-
if (count == 1) then
133-
self.LastPlayed.data = {}
134-
self.m_history_lookup = {}
135-
self.LastPlayed.count = 0
136-
return
137-
end
138-
139-
---@type { action: Action, timestamp: seconds, type: eActionType, fmt: string }?
140-
local entry = table.remove(data, index)
141-
if (entry) then
142-
self.m_history_lookup[entry.action.data.label] = nil
143-
end
144-
self.LastPlayed.count = math.max(0, count - 1)
101+
self.LastPlayed:Pop(index)
145102
end
146103

147104
function YimActions:ClearPlayHistory()
148-
local count = self.LastPlayed.count
149-
if (count == 0) then
150-
return
151-
end
152-
153-
local lastPlayed = self.LastPlayed.data
154-
ThreadManager:Run(function()
155-
for i = count, 1, -1 do
156-
table.remove(lastPlayed, i)
157-
yield(5)
158-
end
159-
self.LastPlayed.count = 0
160-
self.m_history_lookup = {}
161-
end)
105+
self.LastPlayed:Clear()
162106
end
163107

164108
---@param mode ActionHistorySortMode?
165109
function YimActions:SortPlayHistory(mode)
166-
if (mode and mode == self.LastPlayed.sort_mode) then
167-
return
168-
end
169-
170-
mode = mode or self.LastPlayed.sort_mode
171-
table.sort(self.LastPlayed.data, function(a, b)
172-
if (mode == 0) then
173-
return a.timestamp > b.timestamp
174-
elseif (mode == 1) then
175-
return a.type < b.type
176-
end
177-
178-
return a.action.data.label < b.action.data.label
179-
end)
180-
self.LastPlayed.sort_mode = mode
110+
self.LastPlayed:Sort(mode)
181111
end
182112

183113
---@return boolean

SSV2/includes/frontend/yim_actions/actions_ui.lua

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99

1010
---@type Action?
1111
local selectedAction
12-
local sharedDrawFuncs = require("includes.frontend.yim_actions.shared_draw_funcs")
13-
local selectedSidebarItem = 1
12+
local sharedDrawFuncs = require("includes.frontend.yim_actions.shared_draw_funcs")
13+
local sidebarItemIndex = 1
14+
local sidebarTipIndex = 1
1415

1516

1617
local t_ActionsSidebarItems <const> = {
@@ -36,10 +37,16 @@ local t_ActionsSidebarItems <const> = {
3637
},
3738
}
3839

40+
local SideBarTips <const> = {
41+
function() return _F(_T("YAV3_STOP_BTN_HINT"), GVars.keyboard_keybinds.stop_anim) end,
42+
function() return _F(_T("YAV3_SYMBOL_DEFS_HINT"), "[*]", "[C]", "[U]") end,
43+
function() return _T("YAV3_LIST_VIEW_HINT") end,
44+
}
45+
3946
local function DrawSidebarItems()
40-
local selectedTab = t_ActionsSidebarItems[selectedSidebarItem]
47+
local selectedTab = t_ActionsSidebarItems[sidebarItemIndex]
4148
if (selectedTab and selectedTab.callback) then
42-
selectedAction = selectedTab.callback()
49+
selectedAction = selectedTab.callback(selectedTab.label)
4350
end
4451
end
4552

@@ -51,32 +58,52 @@ local function DrawActionsSidebar()
5158
ImGui.Dummy(1, 100)
5259

5360
for i, tab in ipairs(t_ActionsSidebarItems) do
54-
local is_selected = (selectedSidebarItem == i)
61+
local is_selected = (sidebarItemIndex == i)
5562
if (is_selected) then
5663
local r, g, b, a = ImGui.GetStyleColorVec4(ImGuiCol.ButtonActive)
5764
ImGui.PushStyleColor(ImGuiCol.Button, r, g, b, a)
5865
end
5966

6067
if (ImGui.Button(tab.label, is_selected and 150 or 128, 35)) then
6168
GUI:PlaySound("Nav")
62-
if (selectedSidebarItem ~= i) then
69+
if (sidebarItemIndex ~= i) then
6370
selectedAction = nil
6471
end
65-
selectedSidebarItem = i
72+
sidebarItemIndex = i
6673
end
6774

6875
if (is_selected) then
6976
ImGui.PopStyleColor()
7077
end
7178
end
72-
7379
ImGui.PopStyleVar(2)
74-
ImGui.SetWindowFontScale(0.75)
75-
local region = vec2:new(ImGui.GetContentRegionAvail())
76-
local s_SidebarTip = _F(_T("YAV3_STOP_BTN_HINT"), GVars.keyboard_keybinds.stop_anim)
80+
81+
local region = vec2:new(ImGui.GetContentRegionAvail())
82+
local s_SidebarTip = SideBarTips[sidebarTipIndex]()
83+
ImGui.SetWindowFontScale(0.70)
7784
local _, textHeight = ImGui.CalcTextSize(s_SidebarTip, false, region.x)
78-
ImGui.SetCursorPos(0.0, ImGui.GetCursorPosY() + region.y - textHeight - 10)
85+
ImGui.SetCursorPos(0.0, ImGui.GetCursorPosY() + region.y - textHeight - 25)
7986
ImGui.TextWrapped(s_SidebarTip)
87+
if (ImGui.SmallButton(" < ")) then
88+
GUI:PlaySound(GUI.Sounds.Nav)
89+
if (sidebarTipIndex == 1) then
90+
sidebarTipIndex = #SideBarTips
91+
return
92+
end
93+
sidebarTipIndex = sidebarTipIndex - 1
94+
end
95+
GUI:Tooltip(_T("GENERIC_PREVIOUS"))
96+
97+
ImGui.SameLine()
98+
if (ImGui.SmallButton(" > ")) then
99+
GUI:PlaySound(GUI.Sounds.Nav)
100+
if (sidebarTipIndex == #SideBarTips) then
101+
sidebarTipIndex = 1
102+
return
103+
end
104+
sidebarTipIndex = sidebarTipIndex + 1
105+
end
106+
GUI:Tooltip(_T("GENERIC_NEXT"))
80107
ImGui.SetWindowFontScale(1.0)
81108
ImGui.EndChild()
82109
end

SSV2/includes/frontend/yim_actions/companions_ui.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,13 @@ return function()
218218
ImGui.BeginTabBar("##companion_actions_tabbar")
219219
if (ImGui.BeginTabItem("Animations##companions")) then
220220
currentTabName = "companion_anims"
221-
selectedAction = sharedDrawFuncs.DrawAnims()
221+
selectedAction = sharedDrawFuncs.DrawAnims(currentTabName)
222222
ImGui.EndTabItem()
223223
end
224224

225225
if (ImGui.BeginTabItem("Scenarios##companions")) then
226226
currentTabName = "companion_scenarios"
227-
selectedAction = sharedDrawFuncs.DrawScenarios()
227+
selectedAction = sharedDrawFuncs.DrawScenarios(currentTabName)
228228
ImGui.EndTabItem()
229229
end
230230

SSV2/includes/frontend/yim_actions/movement_clipsets_ui.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ local function DrawJsonMovementClipsets()
7474
end
7575

7676
ImGui.BeginDisabled(not jsonClipsetListCreated)
77-
local __t = ClipsetBrowser:SwitchMode("other", jsonArray):Draw()
77+
local __t = ClipsetBrowser:SwitchMode({ mode_name = "other", new_data = jsonArray }):Draw()
7878
ImGui.EndDisabled()
7979

8080
selectedClipset = __t and __t.data or nil
@@ -88,7 +88,7 @@ local function DrawFavoriteMovementClipsets()
8888
return
8989
end
9090

91-
local __t = ClipsetBrowser:SwitchMode("favorites", favorites):Draw()
91+
local __t = ClipsetBrowser:SwitchMode({ mode_name = "favorites", new_data = favorites }):Draw()
9292
selectedClipset = __t and __t.data or nil
9393
end
9494

SSV2/includes/frontend/yim_actions/shared_draw_funcs.lua

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ local function ListFavoritesByCategory(category)
4646
return
4747
end
4848

49-
selectedAction = browser:SwitchMode("favorites", cat):Draw()
49+
selectedAction = browser:SwitchMode({ mode_name = "favorites", new_data = cat, str_id = "favorites" }):Draw()
5050
end
5151

5252
local function DrawFavorites()
@@ -86,31 +86,31 @@ local function DrawFavorites()
8686
end
8787

8888
local function DrawHistory()
89-
local count = YimActions.LastPlayed.count
89+
local actionHistory = YimActions.LastPlayed
90+
local count = actionHistory:GetCount()
9091
if (count == 0) then
9192
ImGui.TextWrapped("Animations, scenarios, and scenes you play will appear here.")
9293
return
9394
end
9495

96+
ImGui.BeginDisabled(actionHistory:IsLocked())
9597
if (GUI:Button(_T("GENERIC_CLEAR"))) then
96-
YimActions:ClearPlayHistory()
98+
actionHistory:Clear()
9799
end
98100
ImGui.Separator()
99101

100102
if (count > 1) then
101-
local sort_mode, clicked = ImGui.Combo(_T("GENERIC_LIST_SORT"), YimActions.LastPlayed.sort_mode, "Time\0Type\0Label\0")
102-
if (clicked) then
103-
YimActions:SortPlayHistory(sort_mode)
104-
end
103+
local sort_mode, clicked = ImGui.Combo(_T("GENERIC_LIST_SORT"), actionHistory:GetSortMode(), "Time\0Type\0Label\0")
104+
if (clicked) then actionHistory:Sort(sort_mode) end
105105
end
106106

107107
if (ImGui.BeginListBox("##playHistory", -1, -1)) then
108108
local button_width = 30
109109
local selectable_width = ImGui.GetContentRegionAvail() - 80
110110
local selectable_height = ImGui.GetTextLineHeight()
111-
local to_eemove = nil
111+
local to_remove = nil
112112

113-
for i, entry in ipairs(YimActions.LastPlayed.data) do
113+
for i, entry in actionHistory:Iter() do
114114
ImGui.SetWindowFontScale(0.8)
115115
ImGui.TextDisabled(DateTime(entry.timestamp):Format("%H:%M"))
116116
ImGui.SetWindowFontScale(1.0)
@@ -122,37 +122,42 @@ local function DrawHistory()
122122
selectedAction = action
123123
end
124124

125-
local rectMin = vec2:new(ImGui.GetItemRectMin())
126-
local rectMax = vec2:new(ImGui.GetItemRectMax())
127-
local hovered = ImGui.IsMouseHoveringRect(rectMin.x, rectMin.y, rectMax.x + button_width, rectMax.y)
128-
if (hovered) then
125+
local rect_min = vec2:new(ImGui.GetItemRectMin())
126+
local rect_max = vec2:new(ImGui.GetItemRectMax())
127+
local is_hovered = ImGui.IsMouseHoveringRect(rect_min.x, rect_min.y, rect_max.x + button_width, rect_max.y)
128+
if (is_hovered) then
129129
ImGui.SameLine()
130130
if (ImGui.SmallButton(" x ")) then
131-
to_eemove = i
131+
to_remove = i
132132
end
133133
GUI:Tooltip(_T("GENERIC_DELETE"))
134134
end
135135
end
136136

137-
if (to_eemove) then
138-
YimActions:RemoveFromHistory(to_eemove)
137+
if (to_remove) then
138+
actionHistory:Pop(to_remove)
139+
to_remove = nil
139140
end
140141
ImGui.EndListBox()
141142
end
143+
ImGui.EndDisabled()
142144

143145
return selectedAction
144146
end
145147

146-
local function DrawAnims()
147-
return Browsers.anims:ResetMode():Draw()
148+
---@param tabName string
149+
local function DrawAnims(tabName)
150+
return Browsers.anims:ResetMode(tabName):Draw()
148151
end
149152

150-
local function DrawScenarios()
151-
return Browsers.scenarios:ResetMode():Draw()
153+
---@param tabName string
154+
local function DrawScenarios(tabName)
155+
return Browsers.scenarios:ResetMode(tabName):Draw()
152156
end
153157

154-
local function DrawScenes()
155-
return Browsers.scenes:ResetMode():Draw()
158+
---@param tabName string
159+
local function DrawScenes(tabName)
160+
return Browsers.scenes:ResetMode(tabName):Draw()
156161
end
157162

158163
return {

SSV2/includes/lib/translations/__hashmap.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,5 +855,7 @@
855855
"GENERIC_ENABLE": 2433038897,
856856
"GENERIC_DISABLE": 566765743,
857857
"VEH_STANCE_UPDATE_WARN": 247724004,
858-
"ASSET_BROWSER_CONTEXT_TT": 1745203944
858+
"ASSET_BROWSER_CONTEXT_TT": 1745203944,
859+
"YAV3_SYMBOL_DEFS_HINT": 4201697999,
860+
"YAV3_LIST_VIEW_HINT": 3504302049
859861
}

SSV2/includes/lib/translations/de-DE.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,5 +855,7 @@ return {
855855
["GENERIC_DISABLE"] = "Deaktivieren",
856856
["GENERIC_ENABLE"] = "Aktivieren",
857857
["VEH_STANCE_UPDATE_WARN"] = "Sind Sie sicher, dass Sie die gespeicherte Haltung für %s überschreiben möchten?",
858-
["ASSET_BROWSER_CONTEXT_TT"] = "Klicken Sie mit der rechten Maustaste, um das Kontextmenü zu öffnen."
858+
["ASSET_BROWSER_CONTEXT_TT"] = "Klicken Sie mit der rechten Maustaste, um das Kontextmenü zu öffnen.",
859+
["YAV3_LIST_VIEW_HINT"] = "Die Animations- und Szenariolistenansichten sind auf den Registerkarten „Aktionen“ und „Gefährten“ genau gleich, was bedeutet, dass alle Filter, die Sie auf einer Registerkarte verwenden, auch auf der anderen vorhanden sind. Dies gilt jedoch nicht für die Registerkarten „Verlauf“ und „Favoriten“.",
860+
["YAV3_SYMBOL_DEFS_HINT"] = "Haben Sie sich jemals gefragt, was die seltsamen Symbole für einige Aktionen in der Liste sind?\n\n- %s: Als Favorit gespeichert.\n- %s: Als Befehl registriert.\n- %s: Vom Benutzer generiert."
859861
}

0 commit comments

Comments
 (0)