Loading a .lua file multiple times...

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.
User avatar
ArchAngel075
Party member
Posts: 319
Joined: Mon Jun 24, 2013 5:16 am

Loading a .lua file multiple times...

Post 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?
caldur
Prole
Posts: 20
Joined: Tue Mar 13, 2012 3:30 pm

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

Post 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.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

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

Post 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
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
dusoft
Party member
Posts: 509
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

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

Post 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/
User avatar
ArchAngel075
Party member
Posts: 319
Joined: Mon Jun 24, 2013 5:16 am

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

Post 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.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

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

Post 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() 

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
markgo
Party member
Posts: 190
Joined: Sat Jan 05, 2013 12:21 am
Location: USA

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

Post 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.
User avatar
ArchAngel075
Party member
Posts: 319
Joined: Mon Jun 24, 2013 5:16 am

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

Post 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.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

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

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
ArchAngel075
Party member
Posts: 319
Joined: Mon Jun 24, 2013 5:16 am

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

Post 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.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 78 guests