generic image
Processing...
  • Games
  • Catalog
  • Develop
  • Robux
  • Search in Players
  • Search in Games
  • Search in Catalog
  • Search in Groups
  • Search in Library
  • Log In
  • Sign Up
  • Games
  • Catalog
  • Develop
  • Robux
   
ROBLOX Forum » Game Creation and Development » Scripting Helpers
Home Search
 

Re: What is an efficient way of doing this?

Previous Thread :: Next Thread 
killjoy37 is not online. killjoy37
Joined: 27 Aug 2008
Total Posts: 2821
11 May 2013 10:13 AM
I have a table that I am constantly traversing, with each index taking one second long before going to the next. When I have reached the end of the table, I have to start back at the beginning. This is not much of a problem. However, while I am iterating through the table, some values may be added to it or removed from it.
When a value is added a part of the table I haven't got to yet in the loop, there is no problem, but when a value is added to a part of the table that the loop has already passed, I need to be able to go to it immediately, and then pick up where I left off, OR, if another value was added yet again behind the stopping place, then I need to go to it.
Report Abuse
jobro13 is not online. jobro13
Joined: 05 Aug 2009
Total Posts: 2865
11 May 2013 10:16 AM
Metatables. The __newindex field provides exactly what you need; it gives the index it wants to get set and the value where it has to be set to. You can then go back to that index and continue to what you were doing.
Report Abuse
killjoy37 is not online. killjoy37
Joined: 27 Aug 2008
Total Posts: 2821
11 May 2013 10:57 AM
Thank you, I'll look into that.
Report Abuse
killjoy37 is not online. killjoy37
Joined: 27 Aug 2008
Total Posts: 2821
12 May 2013 11:00 AM
@Jobro13

About the code you gave me in the message:

local tab = {} -- The table with the stuff in it.
local metatable = {} -- the table where we put the metamethods in.
local linkedtab = {}
metatable.__index = function(tab, ind) return linkedtab[ind] end -- returns the index in the linked table.
metatable.__newindex = function(tab, ind, val) process(ind, val) linkedtab[ind] = val end
setmetatable(tab, metatable)

You said that "tab" was always empty, but I don't understand why, so I'm going to try to explain my problem with the code I created instead so we can be on the same page. It's probably very inefficient, but it looks like it will work. (I can't test it yet).

The actual code is about 80 lines, but I'm omitting some that I know are fine.

isNecessary = false
place = 0
iterator = 1
tower = script.Parent
meta = {
__newindex = function(tab,ind,val)
if val:FindFirstChild("Checker") or tower.Current.Value == val or ind <= iterator then
isNecessary = true
end
rawset(tab,ind,val)
end
}
enemies = setmetatable({},meta)

while #enemies > 0 do
if isNecessary then
tower.Target.Value = enemies[place+1].Value
isNecessary = false
else
tower.Target.Value = enemies[iterator].Value
end
wait(1)
iterator = (iterator + 1)%(#enemies)
end

tower.PotentialTargets.ChildAdded:connect(function(alien)
place = 0
if #enemies > 0 then
--rest of my 80 lines
table.insert(enemies,place+1,nil)
enemies[place+1] = alien
else
enemies[1] = alien
end
end)

So, what happens first is an objectvalue is added to a model called "PotentialTargets" and on the ChildAdded event, I add it to the table "enemies"
If #enemies == 0 then I just put it in the first spot and I'm done, but otherwise I have to figure out where to place it in the table, and that is the part I left out. Then you can see I use table.insert(enemies,place+1,nil).
I did this because I can't simply replace a value with alien, I need to make room for it, and I made it nil so that when I attempted to put alien in that same spot in the next line - enemies[place+1] = alien - it would still trigger the newindex metamethod. Don't worry about place+1.

When it goes to the newindex metamethod, you can see it goes through an if statement.

if val:FindFirstChild("Checker") or tower.Current.Value == val or ind <= iterator then

These are the conditions where I would want it to immediately "process()" alien.
My process() function is just the while loop below the metatable.

Anyway.. If it means one of those conditions, it sets a value isNecessary to true, meaning it is necessary to stop the loop for a moment, "process()" alien, and then go back to the loop. It is important that I go back to the place I stopped in the loop, which is why I have an iterator variable, which tells me where I am in the loop.

I notice that I'm jumping around a lot so I'll finish talking about the metatable, and then start talking about my while loop.

At the end of the metamethod is rawset, where I actually place alien in the table.
In the while loop, I immediately check to see if isNecessary is true, and if it is, then I apply the effects to enemies[place+1] which is where I just placed the alien. Otherwise I just apply the effects to the next value in the table. Then I added 1 to the iterator variable in either case of isNecessary and take the modulus of iterator and #enemies so I can start over. I'm aware that it won't work right at the moment but I'm not worried about the modulus part.

Thanks
Report Abuse
jobro13 is not online. jobro13
Joined: 05 Aug 2009
Total Posts: 2865
19 May 2013 06:05 AM
What I would do is to use table.remove. If you use table.remove it automatically fills gaps. Example:

t = {3,4,5}
table.remove(t,2)
print(t[1], t[2]) -- > 3,5

If you use table.insert(t,val) then it will always be put on the end of the table.

In this case, I don't think you need metatables, as on the point you insert the value, you can immediately process() it?
Report Abuse
killjoy37 is not online. killjoy37
Joined: 27 Aug 2008
Total Posts: 2821
19 May 2013 09:31 AM
This is the only case where it would be immediately processed:

if val:FindFirstChild("Checker") or tower.Current.Value == val or ind <= iterator then

and I used table.insert to make a space where I wanted to insert alien, because I had to push every other value up one. I made it nil because when I actually attempt to set the value of the index I just opened up, it will trigger the metamethod.
With table.insert you can specify where you are inserting the value, by default it is at the end, but I find the correct spot to insert it in code that I didn't show you, open that spot up, then set it.

In the above conditional, I say 'if ind <= iterator then' with this I am just trying to see if placing the alien in the table would place it at a place the loop has already gone through this time around or not, and if it has already been passed up, I go back and process() it.
Report Abuse
jobro13 is not online. jobro13
Joined: 05 Aug 2009
Total Posts: 2865
19 May 2013 09:57 AM
So, what exactly isn't working right now?
Report Abuse
killjoy37 is not online. killjoy37
Joined: 27 Aug 2008
Total Posts: 2821
19 May 2013 10:30 AM
Well, I can't test it yet, but really I was just wondering if the way I was doing it was efficient. Like, if there would be a different way to achieve the same effect, but quicker.
Report Abuse
Previous Thread :: Next Thread 
Page 1 of 1
 
 
ROBLOX Forum » Game Creation and Development » Scripting Helpers
   
 
   
  • About Us
  • Jobs
  • Blog
  • Parents
  • Help
  • Terms
  • Privacy

©2017 Roblox Corporation. Roblox, the Roblox logo, Robux, Bloxy, and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.



Progress
Starting Roblox...
Connecting to Players...
R R

Roblox is now loading. Get ready to play!

R R

You're moments away from getting into the game!

Click here for help

Check Remember my choice and click Launch Application in the dialog box above to join games faster in the future!

Gameplay sponsored by:
Loading 0% - Starting game...
Get more with Builders Club! Join Builders Club
Choose Your Avatar
I have an account
generic image