local function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end assetsCache = nil; assetsCache = assetsCache or {cache = {}, init = false, object = nil} function assetsCache.init(self) self = assetsCache; self.init = true; end function assetsCache.updateIndexesId(self,target,force) if (self or target) then if (target and type(target)=='table') then target = target; self = assetsCache; elseif(self ~= assetsCache) then target = self self = assetsCache end end if (not target or target == self) then return false; end local length = tablelength(target); for key,obj in pairs(target) do if (type(obj)=='userdata' and obj.id and (force or tonumber(obj.id) ~= tonumber(key))) then obj.id = tonumber(key); -- obj.totalCachedObjects = length; end end end function assetsCache.loadImage(self,path,duplicated) local duplicated = (type(duplicated) == 'userdata' and duplicated or (type(path) == 'userdata' and path or false)); local path = (type(path) == 'string' and path or (type (self) == 'string' and self or false)); local self = assetsCache; if (not self or not path) then return false; end if (not self.init) then self:init(); end local filename = path:match("[.+\\]?(.-)$"); local cache,main_obj; cache = (self.cache[stringToMD5String(path)] or self.cache[stringToMD5String(filename)]); if (cache or duplicated) then if (not duplicated and cache) then return cache.objects[1]; end if (not cache and duplicated) then print("Called duplicate but cache object is destroyed??", stringToMD5String(path)) return error(); end else -- if (not cache and not duplicated) then cache = {} cache.path = path; cache.objects = {}; end local method = (ccreatePicture or createPicture); local id = tablelength(cache.objects) + 1; local key = false; if (duplicated) then main_obj = method(); main_obj.assign(duplicated) cache.objects[id] = main_obj key = path; else local file = io.open(path,"r") if (not file) then file = findTableFile(filename) if (file) then main_obj = method(); main_obj.loadFromStream(file.stream); cache.objects[id] = main_obj key = filename; -- file.destroy(); else return false; end else main_obj = method(); main_obj.loadFromFile(path); cache.objects[id] = main_obj key = path; file:close(); end end if (key and not duplicated) then self.cache[stringToMD5String(key)] = cache; end main_obj.id = id; local mt = getmetatable(main_obj) local ex__index = mt.__index local ex__newindex = mt.__newindex mt.__newindex = function(tab,index,value) if ((index == "id" and tonumber(tab.id or -0x799) ~= -0x799) or index ~= "id") then ex__newindex(tab,index,value) end end mt.__index = function(tab,index) if (tostring(index):lower() == 'totalcachedobjects') then return tablelength(cache.objects); elseif (tostring(index):lower() == "destroy" and (tab.id and tonumber(tab.id or -0x799) ~= -0x799)) then table.remove(cache.objects,tonumber(tab.id)); tab.id = -0x799; self.updateIndexesId(self,cache.objects); if (tablelength(cache.objects) < 1) then self.cache[stringToMD5String(key)] = nil; end mt.__index = ex__index mt.__newindex = ex__newindex end return ex__index(tab,index) end local function getCache() if (tonumber(main_obj.id) == -0x799) then return false; end return cache; end local function duplicate() if (tonumber(main_obj.id) == -0x799) then return false; end return self.loadImage(key,main_obj); end if (not duplicated) then local function destroyDuplicates() if (tonumber(main_obj.id) == -0x799) then return false; end for i=tablelength(cache.objects),1,-1 do local obj = cache.objects[i]; if (obj and type(obj)=='userdata' and obj~= main_obj) then obj.destroy(); end end self.updateIndexesId(self,cache.objects,true); end rawset(mt,"destroyDuplicates",destroyDuplicates) end rawset(mt,"duplicate",duplicate) rawset(mt,"id",id) rawset(mt,"getCache",getCache) -- rawset(mt,"totalCachedObjects",function () return tablelength(cache.objects) end) self.updateIndexesId(self,cache.objects,true); return main_obj; end