Sign in to follow this  
rileyriley

coroutine copies

Recommended Posts

I am trying to make a "class" that can spawn many different entities within a game world. I have it hooked up properly to C++ already, and it is creating a new entity within the C++ engine every time I make a new player. However, the coroutines in lua do not seem to be independent - all of my player objects are sharing the same coroutine! A simplified code example:
player = {}

function player:think()
  print("I'm thinking I am: ")
  print(self.name)
  print()
  
  coroutine.yield()
  
  print("In the second half, I am: ")
  print(self.name)
  print()
end

function player:new(o)
	print("Running new function for " .. o.name)
	print()
	
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	
    self.thinkCoroutine = coroutine.create( self.think )
    
    return o 
end

riley = player:new({name = "RILEY"})
carter = player:new({name = "CARTER"})


print ("Now thinking for " .. riley.name)
coroutine.resume(riley.thinkCoroutine, riley)
print()

print ("Now thinking for " .. carter.name)
coroutine.resume(carter.thinkCoroutine, carter)
print ()
This has the following output:
Running new function for RILEY

Running new function for CARTER

Now thinking for RILEY
I'm thinking I am:
RILEY


Now thinking for CARTER
In the second half, I am:
RILEY
As you can see, the riley coroutine is resuming from the carter table, even though I created a new coroutine for carter in the new function. Now, I get proper results if I explicitly re-create the coroutine outside of the new function by changing the last lines of the code to this:
--Add this line to make a new coroutine for carter (I thought this was already done within 'new'!)
carter.thinkCoroutine = coroutine.create(carter.think)

print ("Now thinking for " .. riley.name)
coroutine.resume(riley.thinkCoroutine, riley)
print()

print ("Now thinking for " .. carter.name)
coroutine.resume(carter.thinkCoroutine, carter)
print ()

print ("Now thinking for " .. riley.name)
coroutine.resume(riley.thinkCoroutine, riley)
print()

print ("Now thinking for " .. carter.name)
coroutine.resume(carter.thinkCoroutine, carter)
print ()
Then I get proper output:
Running new function for RILEY

Running new function for CARTER

Now thinking for RILEY
I'm thinking I am:
RILEY


Now thinking for CARTER
I'm thinking I am:
CARTER


Now thinking for RILEY
In the second half, I am:
RILEY


Now thinking for CARTER
In the second half, I am:
CARTER
I really don't want to have to create that coroutine outside of the new function, because I want this to be as easy and seamless as possible for my users. Ideally, they won't need to know about coroutines at all. Why does the second piece of code work when the first fails? I thought that coroutine.create would be called twice, once in each call to new. I must be missing some detail of scope or something... Any help would be appreciated. I'm stumped. PS: Sorry for the crosspost on the lua forums on icynorth.com. Those boards look really inactive.

Share this post


Link to post
Share on other sites
Naturally, I figured the problem out not after the hour of thinking about it but within 5 seconds of asking for help with it.

The new function is being called from the player table, so "player" is self when that coroutine is being created. I fixed the problem by replacing

self.thinkCoroutine = coroutine.create(...)

with

o.thinkCoroutine = coroutine.create(...)

jeez. Duh.

Sorry.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this