My rubbishy cache thingy. Any point?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
IMP1
Prole
Posts: 43
Joined: Mon Oct 03, 2011 8:46 pm

My rubbishy cache thingy. Any point?

Post by IMP1 »

Now, I'm the first to admit that I'm not the oldest cow in the field, and so I'm always wondering whether what I think is a new and genius idea is actually doing any good. So I thought I'd ask whether this here code:

Code: Select all

local aliasNewImage = love.graphics.newImage
local imageCache = {}
function love.graphics.newImage(arg)
  if imageCache[arg] == nil then
    if type(arg) == "string" then -- if it's the filename
      imageCache[arg] = aliasNewImage(arg)
      return imageCache[arg]
    else
      return imageCache[arg]
    end
  else
    return imageCache[arg]
  end
end
is worth doing. Assuming that people know what it's doing. But for those that don't (or just to try and explain my thinking behind it), here goes:
As far as I know, I'm aliasing the method love.graphics.newImage, and then changing it so if the image is already in the table 'cache', it returns the already loaded image, rather than loading it again, and if the image is *not* in the table 'cache', it puts it in there. Of course, if the parameter isn't the filename, it acts as normal.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: My rubbishy cache thingy. Any point?

Post by kikito »

Good idea, but already done - several times :3 . Here's my take on it: memoize.lua

memoize is a function applied to another function. It returns a "memoized version" of that function. The equivalent code using memoize would be:

Code: Select all

local memoize = require 'memoize'
love.graphics.newImage = memoize(love.graphics.newImage)
It would work with any other functions. Things like the number of parameters accepted or values returned are taken into account.
When I write def I mean function.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: My rubbishy cache thingy. Any point?

Post by Robin »

newImage is not a function that would benefit the most from memoization, I'd say, because you typically only call newImage in love.load(), once per image. Something like this might be useful if you are loading levels dynamically as you play, though: you create new images for the new level, but only those you don't already have.
Help us help you: attach a .love.
User avatar
tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

Re: My rubbishy cache thingy. Any point?

Post by tentus »

In one of my games I created images by pasting corners etc together. I used a function similar to what you have to make it more efficient, that way if the image had been created before we could just load it from memory. I even wrote a little loop to use the spare cpu cycles in the menu to pre-generate the images, that way the levels would load faster, but I didn't like how quickly it ate memory, so I removed that part.
Kurosuke needs beta testers
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: My rubbishy cache thingy. Any point?

Post by vrld »

I use a proxy table for lazy loading of any resouce:

Code: Select all

function Proxy(f)
	return setmetatable({}, {__index = function(self, k)
		local v = f(k)
		rawset(self, k, v)
		return v
	end})
end
And then for example:

Code: Select all

State = Proxy(function(k) return assert(love.filesystem.load('states/'..k..'.lua'))() end)
Font  = Proxy(function(k) return love.graphics.newFont('font/font.ttf', k) end)
Image = Proxy(function(k) return love.graphics.newImage('img/' .. k .. '.png') end)
Images can be accessed by Image.<image-name> and fonts of different size by Font[<size>]:

Code: Select all

love.graphics.draw(Image.bomb, x,y, self.shape:rotation(),1,1, 32,32)
love.graphics.setFont(Font[30])
This isn't so much to make the game faster but to speed up the coding process.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
thelinx
The Strongest
Posts: 857
Joined: Fri Sep 26, 2008 3:56 pm
Location: Sweden

Re: My rubbishy cache thingy. Any point?

Post by thelinx »

That doesn't actually cache stuff though, does it?

I'd change it to

Code: Select all

function Proxy(f)
	return setmetatable({}, {__index = function(self, k)
		return rawget(self, k) or (rawset(self, k, f(v)) and rawget(self, k))
	end})
end
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: My rubbishy cache thingy. Any point?

Post by vrld »

It does cache. The __index method is only invoked if the key does not exist:

Code: Select all

> t = setmetatable({}, {__index = function(t,k) print('__index'); t[k] = k; return k end})
> print(t.foo)
__index
foo
> print(t.foo)
foo
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
thelinx
The Strongest
Posts: 857
Joined: Fri Sep 26, 2008 3:56 pm
Location: Sweden

Re: My rubbishy cache thingy. Any point?

Post by thelinx »

Huh. Okay.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 7 guests