File size: 3,053 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
-- Supports storing of editor data via :EditorData() and tracking dirty status
DefineClass("GedEditedObject")
if FirstLoad then
g_GedEditorData = setmetatable({}, weak_keys_meta)
g_DirtyObjects = {}
g_DirtyObjectsById = {}
end
local function notify_dirty_status(obj, dirty)
g_DirtyObjects[obj] = dirty or nil
GedUpdateDirtyObjectsById()
GedNotify(obj, "OnEditorDirty", dirty)
for id, ged in pairs(GedConnections) do
GedUpdateObjectValue(ged, nil, "root|dirty_objects")
end
end
function GedEditedObject:EditorData()
local data = g_GedEditorData[self]
if not data then
data = {}
g_GedEditorData[self] = data
end
return data
end
-- calculate original hash when the object is displayed in Ged for editing
function OnMsg.GedBindObj(obj)
while obj do
if IsKindOf(obj, "GedEditedObject") then
obj:TrackDirty()
end
obj = ParentTableCache[obj]
end
end
-- update current hash when the object is modified in Ged
function OnMsg.ObjModified(obj)
while obj do
if IsKindOf(obj, "GedEditedObject") and obj:IsOpenInGed() then
obj:UpdateDirtyStatus()
end
obj = ParentTableCache[obj] and GetParentTableOfKind(obj, "GedEditedObject")
end
end
function GedEditedObject:IsOpenInGed()
assert(false, "Not implemented") -- please implement in the children classes
end
function GedEditedObject:TrackDirty()
local data = self:EditorData()
if not data.old_hash then
data.old_hash = self:CalculatePersistHash()
data.current_hash = data.old_hash
end
end
function GedEditedObject:UpdateDirtyStatus()
local data = self:EditorData()
local old_hash = data.old_hash
if old_hash then
local new_hash = self:CalculatePersistHash()
if data.current_hash ~= new_hash then
data.current_hash = new_hash
notify_dirty_status(self, old_hash ~= new_hash)
end
end
end
function GedEditedObject:IsDirty()
local data = self:EditorData()
local old_hash = data.old_hash
return old_hash and (old_hash == 0 or old_hash ~= data.current_hash)
end
function GedEditedObject:MarkDirty(notify)
if not self:IsDirty() then
self:EditorData().old_hash = 0
if notify ~= false then
notify_dirty_status(self, true)
end
end
end
function GedEditedObject:MarkClean()
local data = self:EditorData()
data.current_hash = self:CalculatePersistHash()
if self:IsDirty() then
data.old_hash = data.current_hash
notify_dirty_status(self, false)
end
end
----- Send dirty objects to Ged, so * modified marks can be displayed for them
function GedUpdateDirtyObjectsById()
local dirty = {}
for obj in pairs(g_DirtyObjects) do
dirty[tostring(obj)] = true
-- mark a preset as dirty if any of its linked presets (defined via a linked_presets property) are dirty
for parent_preset, linked_presets in pairs(LinkedPresetClasses) do
if table.find(linked_presets, obj.class) then
local obj = FindLinkedPresetOfClass(obj, parent_preset)
if obj then
dirty[tostring(obj)] = true
end
end
end
end
g_DirtyObjectsById = dirty
end
function GedGetDirtyObjects(obj, filter, preset_class)
return g_DirtyObjectsById
end
|