Page 1 of 2

Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 7:57 am
by ArchAngel075
In a project i am busy with i need to load/require a file multiple times to give it to objects i create, and it seems it cant be done.


Firstly, I can create/instance a new enemy class and assign it a .lua file to set its AI behavior.
Except that if i create one enemy, and have it require(behavior_script) and then start working with the script and then create a second enemy and do the same they both seem to access the same script, thus each time a behavior.update() call is made from the enemy the script is updated twice or n(number enemies) times.


I have tried to make the script act as a class object as well but it produces the same results strangely.
EDIT--- I reattempted this and it seems to work, though its annoying to need to treat these simple .lua files that return a table of functions to operate on as class objects. Preferably i would like to maybe use something like a deepcopy that handles functions aswell to duplicate a script?


I think that if a use love.filesystem.read and then loadstring or create a temp file, require it, delete the temp file ... I can make sure its entirely a new script thats loaded.


Any ideas on how to fix this issue?

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 10:07 am
by caldur
er... simple solution: use dofile instead of require. require is designed to avoid loading the same file more than once.
That being said, my feeling is that the entity itself should be responsible for keeping its states, instead of storing the state in the behavior script. But that's just my own opinion.

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 10:12 am
by zorg
i'm assuming your lua file has something like

Code: Select all

return aiTable
at the end of it, since you assign it via require to a variable.
Just change that to something like

Code: Select all

return setmetatable({state,variables,go,here},aiTableOfMethodsOnly)
That will make it instantiable, if i didn't mess up :3

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 3:36 pm
by dusoft
Check this state manager/switcher, it load the same file over and over without a problem:
http://www.ambience.sk/love2d-a-state-s ... class-lua/

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 5:51 pm
by ArchAngel075
The state switcher seems to not be what i need i think...

@zborg
I might attempt the suggested method if i can rally myself to edit the aiBehaviour scripts to not be a instanced object (my current workaround)
Though im not sure about it, the "state variables go here", would that be the default variables i would like to assign?

Some further clarification about my .lua file is shown :
the file will look something like this :

Code: Select all

local aiBehaviour = {}
aiBehaviour.mainNode = 1
aiBehaviour.ended = false
aiBehaviour.parent = nil

function aiBehaviour.update()
 --do stuff related to a update tick of the ai behaviour.
end

function aiBehaviour.setParent(p)
 aiBehaviour.parent = p
end

return aiBehaviour
The update function is called by the enemyObject that uses it.
The parent variable is set to the enemyObject in question, this is so the aiBehaviour script can interface with that enemy it is used by.

Would I then do :
instead of 'return aiBehaviour" do :

Code: Select all

local methodTable = {
 update = aiBehaviour.update,
 setParent = aiBehaviour.setParent,
}

local defaultVars = {
 mainNode = aiBehaviour.mainNode,
 ended = aiBehaviour.ended,
 parent = aiBehaviour.parent,
}

 return setmetatable( defaultVars , methodTable )
What im looking for is more alike to zborgs definition, a lua file that one can instantiate over and over to assign to a variable where is instance is a clean default of the original ready for operations.

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 6:25 pm
by s-ol
Instead of aiBehavior.update() just put aibehavior:update () and use one of the many OOP options! For example:

Code: Select all

local AiBehavior = { value=3 } 
Aibehavior.__index = AiBehavior  - - look for methods of instances here

function AiBehavior.create() - - "static" constructor
    local self = setmetatable( {}, AiBehavior )
    - -  initialize 
    return self
end

function AiBehavior:printValue()
    print( self.value)
end

function AiBehavior:doSthWithParameters( param ) 
    self.value = self.value + param
    self:printValue()
end

return AiBehavior
Main file:

Code: Select all

AiBehavior = require "aibehavior" 
... 
local instance = AiBehavior.create()
instance:doSthWithParameters( 3 ) 
instance:update() 

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 6:26 pm
by markgo
I would suggest returning a table with an ":init" or ":clear" method so you don't have to reload a file. You can simply call your function to reset or reload stuff.

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 6:51 pm
by ArchAngel075
Yes i currently do that already, infact i had setup a really powerful asset module for my engine.
I can create "mods" that have assets, each asset has a asset.lua and asset.ini (the ini is redundant atm until it gains a use really)

Next if i use _astils.newObjectInstance(object) i create a new instance of it, clean with automated :init() call

Whats powerful is mods are loaded in a database inside the engine in a cirtual filesystem based on the mods folderstructure.
For instance, a mod "MyMod" exists, in it is assets "myAsset" and "myAsset2"
Now to access those assets for instancing (arg passed to newObject instance) one would simply put the virtual path to that asset as the rule/common courtesy is that a mods folder structure should never change unless as a major update.

to make a enemy called E01 in a enemies folder under "MyMod" i can do

myEnemy = _astils.newObjectInstance(_astils.protodatabase.Mods.MyMod.Enemies.E01)

Anything erlying on another mods' contents can also use straight up references because the location of that asset should never change inside of the mod, the location of the mod can be anywhere within the mods folder, it will allways be _astils.protodatabase.Mods.MODNAME



Now scripts and non-assets (i call em CurseAssets) behave abit differently when interpreted by the asset module, instead a require or read data (love.filesystem.read) is used, though a require of a .lua file who has a variable ._isScript set to true is treated as a script.

The desired outcome is to be able to duplicate the scripts using a _astils.newScriptInstance(script).

I dont want to treat the scripts as curseAssets because its more cleaner to include the behaviour_0n.lua file with the asset (asset can access using self._path to fetch its path, then edit that path in anoher variable to point to script and load it, it use newScriptInstance)

Preferably its more cleaner to because assets require a folder of their own to house the asset.lua and asset.ini.

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 7:06 pm
by s-ol
ArchAngel075 wrote:Yes i currently do that already, infact i had setup a really powerful asset module for my engine.
I can create "mods" that have assets, each asset has a asset.lua and asset.ini (the ini is redundant atm until it gains a use really)

Next if i use _astils.newObjectInstance(object) i create a new instance of it, clean with automated :init() call

Whats powerful is mods are loaded in a database inside the engine in a cirtual filesystem based on the mods folderstructure.
For instance, a mod "MyMod" exists, in it is assets "myAsset" and "myAsset2"
Now to access those assets for instancing (arg passed to newObject instance) one would simply put the virtual path to that asset as the rule/common courtesy is that a mods folder structure should never change unless as a major update.

to make a enemy called E01 in a enemies folder under "MyMod" i can do

myEnemy = _astils.newObjectInstance(_astils.protodatabase.Mods.MyMod.Enemies.E01)

Anything erlying on another mods' contents can also use straight up references because the location of that asset should never change inside of the mod, the location of the mod can be anywhere within the mods folder, it will allways be _astils.protodatabase.Mods.MODNAME



Now scripts and non-assets (i call em CurseAssets) behave abit differently when interpreted by the asset module, instead a require or read data (love.filesystem.read) is used, though a require of a .lua file who has a variable ._isScript set to true is treated as a script.

The desired outcome is to be able to duplicate the scripts using a _astils.newScriptInstance(script).

I dont want to treat the scripts as curseAssets because its more cleaner to include the behaviour_0n.lua file with the asset (asset can access using self._path to fetch its path, then edit that path in anoher variable to point to script and load it, it use newScriptInstance)

Preferably its more cleaner to because assets require a folder of their own to house the asset.lua and asset.ini.
I really dont see your problem with regular OOP, it does exactly what you want - seperate data from code so you dont have to store your functions (the code) in every instance, but in the metatable. Deep copies take time and waste resources.

Re: Loading a .lua file multiple times...

Posted: Sun Nov 02, 2014 7:34 pm
by ArchAngel075
hmm well seeing as ive already edited the file to be use OOP ill stick to it, it was more a matter of preference than function. Perhaps i can work on a setup that makes it easier while keeping OOP...

Anyhow thanks for the help, i might use the instancing lua files in another project in the future - learnt something new to play with afterall.