This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
timikx's profile picture

os.pullEvent(): another way how to not lose events while waiting for another event

Started by timikx, 19 June 2013 - 01:55 AM
timikx #1
Posted 19 June 2013 - 03:55 AM
Hi I have question about events:
I've made my version of programs for BdoubleO's and Etho's call of dutty map. I have main computer which is checking various events and then working with them. I'm using wireless modem, player detector, chatbox, touch screen and inputs from bundled cable.

Before I played just with turtles so this was my first time working with monitors and events.
It was kind of like learning experiment for me, code could be cleaned surely but the program is working so I am happy.

So before I discovered that you can increase number of messages from chat box per second in miscperipherals config file, my program was terminated because sometimes it send more than 1 chat box message per second.

From my understanding of events:
they are stored in event queue and can be pulled with os.pullEvent() but when you use sleep(), read() or some other commands (I don't know them all) the queue will be cleared.

So in order to avoid termination of my program I need to somehow place delay after chatbox.say() command but also don't destroy events that happens during the delay.
So I made wait() function that starts another timer, and during the timer time checks events (os.pullEvent) and then filters only events I care about and store them in table. After time passes all events in table are placed to event queue (os.queueEvent).

I was just wandering is there some function or trick how to do this differently or easily.

I think I don't need to use my wait() function any more because I increased the number of messages from chat box to 25 per second but i kept it just for safety.

Thanks for answers.

wait() function:
Spoiler

function wait(wtime)
timer2=os.startTimer(wtime)
events={}
repeat
  event,parm1,parm2,parm3,parm4=os.pullEvent()
  click=checkxy(parm2, parm3)
  if (event=="timer" and parm1==timer) or   -- game timer
   (event=="chat_death" and (
	game.teams[1].players[parm1]~=nill or
	game.teams[2].players[parm1]~=nill or
	game.teams[1].players[parm2]~=nill or
	game.teams[2].players[parm2]~=nill)) or
   event=="redstone"
  then
   table.insert(events,{event,parm1,parm2,parm3,parm4})
  end
until (event=="timer" and parm1==timer2) or (event=="chat" and parm2=="stop game")

for i=1,#events do
  os.queueEvent(events[i][1],events[i][2],events[i][3],events[i][4],events[i][5])
end
end

demostration is in this video (it has bad frame rate - I know)
[media]http://www.youtube.com/watch?v=0X_hu2AY3uA[/media]

Programs and world download:
http://www.mediafire...bkhg71efleuh3ec


All programs:

Main:
Spoiler

function initmainpc()
scorechat=25
chatbox=peripheral.wrap("bottom")
detector=peripheral.wrap("front")
modem=peripheral.wrap("right")
modem.open(1)
monitor=peripheral.wrap("top")
-- back side is for bundled cable
game={points = {A=0, B=0, C=0}, scoretime=5, winningscore= 250, teams = {[1]={name="Green", score=0,players={}}, [2]={name="Blue", score=0,players={}}}}
button={}
monitor.setBackgroundColor(colors.black)
monitor.setTextScale(1)
monitor.setTextColor(colors.white)
fillTable()
screen()
end
function start()
initmainpc()
repeat
  -- chatbox.say("choose: 1 - team 1 name, 2 - team 2 name, 3 - set player, 4 - custom winning score, 5 - new game, 6 - quit",100,false)
  event,parm1,parm2,parm3=os.pullEvent()
   if event=="chat" then
	parm2=tonumber(parm2)
	if parm2==1 then team1name() end
	if parm2==2 then team2name() end
	if parm2==3 then setplayers() end
	if parm2==4 then customwinningscore() end
	if parm2==5 then startnewgame() end
   end
   if event=="monitor_touch" then
	click=checkxy(parm2, parm3)
	if click=="team1name" then team1name() end
	if click=="team2name" then team2name() end
	if click=="set" then setplayers() end
	if click=="change" then changeplayers() end
	if click=="custom" then customwinningscore() end
	if click=="start" then startnewgame() end
	if click=="s250" then
	 button.score.text="250"
	 game.winningscore=250
	 sendscore()
	 screen()
	end
	if click=="s500" then
	 button.score.text="500"
	 game.winningscore=500
	 sendscore()
	 screen()
	end
	if click=="s1000" then
	 button.score.text="1000"
	 game.winningscore=1000
	 sendscore()
	 screen()
	end
	if click=="s2000" then
	 button.score.text="2000"
	 game.winningscore=2000
	 sendscore()
	 screen()
	end
   end
until parm2==6
end
function setTable(name, text, x, y, color)
  button[name] = {}
button[name]["color"] = color
  button[name]["x"] = x
  button[name]["y"] = y
button[name]["text"] = text
end
function fillTable()
setTable("title","Minecraft Black Ops", 6, 1,colors.orange)
setTable("winningscore", "Winning score:", 2, 3,colors.black)
setTable("score", tostring(game.winningscore), 17, 3,colors.black)
setTable("s250","250", 2, 4,colors.red)
setTable("s500","500", 6, 4,colors.red)
setTable("s1000","1000", 10, 4,colors.red)
setTable("s2000","2000", 15, 4,colors.red)
setTable("custom","Custom", 20, 4,colors.red)
setTable("team1name","Team 1 name:", 2, 6,colors.red)
setTable("team2name","Team 2 name:", 15, 6,colors.red)
setTable("team1",game.teams[1].name, 2, 7,colors.green)
setTable("team2",game.teams[2].name, 15, 7,colors.blue)
setTable("players","Players", 2, 9,colors.black)
setTable("set","Set", 10, 9,colors.red)
setTable("change","Change", 14, 9,colors.black)
setTable("done","Done", 21, 9,colors.black)
setTable("start","Start new game", 2, 11,colors.black)
setTable("stop","Stop game", 20, 11,colors.black)
end	
function fill(text, color, bData)
monitor.setBackgroundColor(color)
monitor.setCursorPos(bData["x"], bData["y"])
monitor.write(text)
monitor.setBackgroundColor(colors.black)
end
	
function screen()
monitor.clear()
  for name,data in pairs(button) do
	fill(data.text, data.color, data)
  end
end
function checkxy(x, y)
  for name, data in pairs(button) do
	  if y==data["y"] then
	 if x>=data["x"] and x<= data["x"]+string.len(data.text)-1 then
	  if data.color==colors.red then
	   return name
	  end
	 end
	  end
  end
   return nill
end  
function playeradd(name,team)
if game.teams[team].players[name]==nill then
  if team==1 then otherteam=2 else otherteam=1 end
  if game.teams[otherteam].players[name]~=nill then
   game.teams[otherteam].players[name]=nill
   sendplayer(otherteam,name,"remove",0,0)
  end --removes player from other team if he is in it.
  game.teams[team].players[name]={}
  chatbox.say(name.." joined "..game.teams[team].name,100,false)
  sendplayer(team,name,"add",0,0)
  wait(0.04,"players")
else
  game.teams[team].players[name]=nill
  chatbox.say(name.." left from "..game.teams[team].name,100,false)
  sendplayer(team,name,"remove",0,0)
  wait(0.04,"players")
end

end
function setplayers()

game.teams[1].players={}
game.teams[2].players={}
sendplayer(1," ","clear",0,0)
sendplayer(2," ","clear",0,0)
changeplayers()
end
function changeplayers()
done=false
chatbox.say("To join or leave teams just click player detector of choosen team. To finnish click on: Done",100,false)
sleep(0.04)
button.set.color=colors.black
button.change.color=colors.black
button.done.color=colors.red
screen()
repeat
  event,parm1,parm2,parm3,parm4=os.pullEvent()
  if event=="modem_message" then
   playeradd(parm4,1)
  end
  if event=="player" then
   playeradd(parm1,2)  
  end
  if event=="monitor_touch" then
   click=checkxy(parm2, parm3)  
   if click=="done" then
	done=true  
   else
	chatbox.say("To finnish click on: Done",100,false)
	wait(0.04,"players")
   end  
  end
  if event=="chat" and parm2=="done" then  
   done=true
  end
until done==true
button.done.color=colors.black
button.change.color=colors.red
button.set.color=colors.red
button.start.color=colors.red
screen()
end
function team1name()
chatbox.say("Type Team 1 name",100,false)
sleep(0.04)
event,parm1,parm2=os.pullEvent("chat")
game.teams[1].name=parm2
button.team1.text=parm2
sendscore()
sendplayer(1,parm2,"team",0,0)
screen()
chatbox.say("Team 1 name changed to "..parm2,100,false)
sleep(0.04)
end
function team2name()
chatbox.say("Type Team 2 name",100,false)
sleep(0.04)
event,parm1,parm2=os.pullEvent("chat")
game.teams[2].name=parm2
button.team2.text=parm2
sendscore()
sendplayer(2,parm2,"team",0,0)
screen()
chatbox.say("Team 2 name changed to "..parm2,100,false)
sleep(0.04)
end
function customwinningscore()
chatbox.say("type custom winning score",100,false)
sleep(0.04)
done=false
repeat
  event,parm1,parm2,parm3=os.pullEvent()
  if event=="chat" then
   if parm2=="done" then
	done=true
   else  
	score=tonumber(parm2)  
	if type(score)=="number" then
	 game.winningscore=score
	 done=true
	 button.score.text=tostring(parm2)
	 sendscore()
	 screen()
	 chatbox.say("Winning score was set to "..parm2,100,false)	
	else
	 chatbox.tell(parm1,"Wrong winning score. Type a number")
	end
   end
  end
until done==true
sleep(0.04)
end
function resetpoints()
for i=1,2 do
  redstone.setBundledOutput("back", colors.pink)
  sleep(0.2)
  redstone.setBundledOutput("back", 0)
  sleep(0.2)
end
end
function increasescore()
team1=0
team2=0
if game.points.A==1 then team1=team1+1
  elseif game.points.A==2 then team2=team2+1 end
if game.points.B==1 then team1=team1+1
  elseif game.points.B==2 then team2=team2+1 end
if game.points.C==1 then team1=team1+1
  elseif game.points.C==2 then team2=team2+1 end
return {[1]=team1,[2]=team2}
end
function sendscore()
modem.transmit(2, 10, game.teams[1].score.."°"..game.teams[2].score.."°"..game.winningscore.."°"..game.points.A.."°"..game.points.B.."°"..game.points.C.."°"..game.teams[1].name.."°"..game.teams[2].name)
end
function sendplayer(team,name,state,kills,deaths)
if team == 1 then
  ch1=3
else
  ch1=4  
end
modem.transmit(ch1, 10, name.."°"..state.."°"..kills.."°"..deaths)
end
function startnewgame()
game.teams[1].score=0
game.teams[2].score=0
game.points={A=0, B=0, C=0}
sendscore()
for i=1,2 do
  for name, data in pairs(game.teams[i].players) do
   game.teams[i].players[name].kills=0
   game.teams[i].players[name].deaths=0
  end
end
button.start.color=colors.black
button.s250.color=colors.black
button.s500.color=colors.black
button.s1000.color=colors.black
button.s2000.color=colors.black
button.custom.color=colors.black
button.team1name.color=colors.black
button.team2name.color=colors.black
button.set.color=colors.black
button.change.color=colors.black
screen()
chatbox.say("To start new game go to your team starting place and type: start",100,false)
sleep(0.04)
repeat
  event,parm1,parm2=os.pullEvent("chat")
until parm2=="start"
for i=5,1,-1 do
  chatbox.say("The game will start at "..i,100,false)
  resetpoints()
  sleep(0.6)
end
chatbox.say("Begin")
button.stop.color=colors.red
screen()
sleep(0.04)
chatbox.say("To stop the game type: stop game or click on: Stop game",100,false)
sleep(0.04)
redstone.setBundledOutput("back", colors.green)
timer=os.startTimer(game.scoretime)
stop=false
repeat
  event,parm1,parm2,parm3=os.pullEvent()
  if event=="timer" and parm1==timer then
   newscore=increasescore()
   if math.floor(game.teams[1].score/scorechat)<math.floor((game.teams[1].score+newscore[1])/scorechat) then
	chatbox.say(game.teams[1].name..": "..game.teams[1].score+newscore[1].." points, "..game.teams[2].name..": "..game.teams[2].score.." points",100,false)
	wait(0.04,"game")
   end
   game.teams[1].score=game.teams[1].score+newscore[1]

   if math.floor(game.teams[2].score/scorechat)<math.floor((game.teams[2].score+newscore[2])/scorechat) then
	chatbox.say(game.teams[1].name..": "..game.teams[1].score.." points, "..game.teams[2].name..": "..game.teams[2].score+newscore[2].." points",100,false)
	wait(0.04,"game")
   end
   game.teams[2].score=game.teams[2].score+newscore[2]

   sendscore()

   if game.teams[1].score>=game.winningscore or game.teams[2].score>=game.winningscore then
	if game.teams[1].score==game.teams[2].score then
	 chatbox.say("Draw game. No winner",100,false)
	 wait(0.04,"game")
	elseif game.teams[1].score>game.teams[2].score then
	 chatbox.say(game.teams[1].name.." wins the game")
	 sleep(0.04)
	 chatbox.say(game.teams[1].name..": "..game.teams[1].score.." points, "..game.teams[2].name..": "..game.teams[2].score.." points",100,false)
	 sleep(0.04)
	else
	 chatbox.say(game.teams[2].name.." wins the game.",100,false)
	 sleep(0.04)
	 chatbox.say(game.teams[1].name..": "..game.teams[1].score.." points, "..game.teams[2].name..": "..game.teams[2].score.." points",100,false)
	 sleep(0.04)
	end
	stop=true
   else
	timer=os.startTimer(game.scoretime)
   end


  elseif event=="chat_death" then
   if game.teams[1].players[parm1]~=nill then
	game.teams[1].players[parm1].deaths=game.teams[1].players[parm1].deaths+1
	chatbox.say(parm1.." died "..game.teams[1].players[parm1].deaths.." times",100,false)
	sendplayer(1,parm1,"update",game.teams[1].players[parm1].kills,game.teams[1].players[parm1].deaths)
	wait(0.04,"game")
   elseif game.teams[2].players[parm1]~=nill then
	game.teams[2].players[parm1].deaths=game.teams[2].players[parm1].deaths+1
	chatbox.say(parm1.." died "..game.teams[2].players[parm1].deaths.." times",100,false)
	sendplayer(2,parm1,"update",game.teams[2].players[parm1].kills,game.teams[2].players[parm1].deaths)
	wait(0.04,"game")
   end
   if game.teams[1].players[parm2]~=nill then
	game.teams[1].players[parm2].kills=game.teams[1].players[parm2].kills+1
	chatbox.say(parm2.." has "..game.teams[1].players[parm2].kills.." kills",100,false)
	sendplayer(1,parm2,"update",game.teams[1].players[parm2].kills,game.teams[1].players[parm2].deaths)
	wait(0.04,"game")
   elseif game.teams[2].players[parm2]~=nill then
	game.teams[2].players[parm2].kills=game.teams[2].players[parm2].kills+1
	chatbox.say(parm2.." has "..game.teams[2].players[parm2].kills.." kills",100,false)
	sendplayer(2,parm2,"update",game.teams[2].players[parm2].kills,game.teams[2].players[parm2].deaths)
	wait(0.04,"game")
   end


  -- A1	  A2	  B1	   B2		C1	   C2
  --  colors.white  colors.orange colors.magenta  colors.lightBlue  colors.yellow  colors.lime

  elseif event=="redstone" then
   cable=redstone.getBundledInput("back")
   if colors.test(cable, colors.white) and game.points.A~=1 then
	game.points.A=1
	chatbox.say(game.teams[1].name.." captured A",100,false)
	wait(0.04,"game")
   elseif colors.test(cable, colors.orange) and game.points.A~=2 then
	game.points.A=2
	chatbox.say(game.teams[2].name.." captured A",100,false)
	wait(0.04,"game")
   end
   if colors.test(cable, colors.magenta) and game.points.B~=1 then
	game.points.B=1
	chatbox.say(game.teams[1].name.." captured B",100,false)
	wait(0.04,"game")
   elseif colors.test(cable, colors.lightBlue) and game.points.B~=2 then
	game.points.B=2
	chatbox.say(game.teams[2].name.." captured B",100,false)
	wait(0.04,"game")
   end
   if colors.test(cable, colors.yellow) and game.points.C~=1 then
	game.points.C=1
	chatbox.say(game.teams[1].name.." captured C",100,false)
	wait(0.04,"game")
   elseif colors.test(cable, colors.lime) and game.points.C~=2 then
	game.points.C=2
	chatbox.say(game.teams[2].name.." captured C",100,false)
	wait(0.04,"game")
   end
   sendscore()

  elseif event=="chat" and parm2=="stop game" then  
   stop=true
   chatbox.say("Game stoped",100,false)
   sleep(0.04)  
  elseif event=="monitor_touch" then
   click=checkxy(parm2, parm3)  
   if click=="stop" then
	stop=true
	chatbox.say("Game stoped",100,false)
	sleep(0.04)  
   end
  end

until stop==true
redstone.setBundledOutput("back", colors.red)
sleep(0.2)
redstone.setBundledOutput("back", 0)
button.start.color=colors.red
button.stop.color=colors.black
button.s250.color=colors.red
button.s500.color=colors.red
button.s1000.color=colors.red
button.s2000.color=colors.red
button.custom.color=colors.red
button.team1name.color=colors.red
button.team2name.color=colors.red
button.set.color=colors.red
button.change.color=colors.red
screen()
sleep(0.04)
end
function wait(wtime,wtype)
timer2=os.startTimer(wtime)
events={}
repeat
  event,parm1,parm2,parm3,parm4=os.pullEvent()
  click=checkxy(parm2, parm3)
  if (wtype=="game" and (
   (event=="timer" and parm1==timer) or
   (event=="chat_death" and (
	game.teams[1].players[parm1]~=nill or
	game.teams[2].players[parm1]~=nill or
	game.teams[1].players[parm2]~=nill or
	game.teams[2].players[parm2]~=nill)) or
   (event=="redstone")  
   ))
  or (wtype=="players" and (
   (event=="monitor_touch" and click=="done") or
   (event=="chat" and parm2==done) or
   event=="modem_message" or
   event=="player"))
  then
   table.insert(events,{event,parm1,parm2,parm3,parm4})
  end
until (event=="timer" and parm1==timer2) or click=="stop" or (event=="chat" and parm2=="stop game")

for i=1,#events do
  os.queueEvent(events[i][1],events[i][2],events[i][3],events[i][4],events[i][5])
end
end
start()

Detecotor
Spoiler

function startup()
detector=peripheral.wrap("front")
Modem=peripheral.wrap("left")
while true do
event,player=os.pullEvent("player")
print(player.." clicked")
Modem.transmit(1, 10, player)
end
end

startup()

Score
Spoiler

function init()
modem=peripheral.wrap("back")
modem.open(2)
monitor=peripheral.wrap("top")
button={}
monitor.setBackgroundColor(colors.black)
monitor.setTextScale(2)
monitor.setTextColor(colors.white)
color1=colors.green
color2=colors.blue
A=""
B=""
C=""
T1="0"
T2="0"
WS="250"
team1="Green"
team2="Blue"
fillTable()
screen()
end

function setTable(name, text, x, y, color)
  button[name] = {}
button[name]["color"] = color
  button[name]["x"] = x
  button[name]["y"] = y
button[name]["text"] = text

end

function fillTable()
if A=="1" then
colorA=color1
A=team1
elseif A=="2" then
colorA=color2
A=team2
else
colorA=colors.black
A=""
end
if B=="1" then
colorB=color1
B=team1
elseif B=="2" then
colorB=color2
B=team2
else
colorB=colors.black
B=""
end
if C=="1" then
colorC=color1
C=team1
elseif C=="2" then
colorC=color2
C=team2
else
colorC=colors.black
C=""
end
setTable("A","A: "..A, 1, 1,colorA)
setTable("B","B: "..B, 1, 2,colorB)
setTable("C","C: "..C, 1, 3,colorC)
setTable("winscore","Win score", 1, 4,colors.black)
setTable("score",WS, 11, 4,colors.black)
setTable("team1",team1, 1, 5,color1)
setTable("team1score",T1, 11, 5,color1)
setTable("team2",team2, 1, 6,color2)
setTable("team2score",T2, 11, 6,color2)
end	

function fill(text, color, bData)
monitor.setBackgroundColor(color)
monitor.setCursorPos(bData["x"], bData["y"])
monitor.write(text)
monitor.setBackgroundColor(colors.black)
end

function screen()
monitor.clear()
  for name,data in pairs(button) do
	fill(data.text, data.color, data)
  end
end

function split(pString, pPattern)
   local Table = {}
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
	  if s ~= 1 or cap ~= "" then
	 table.insert(Table,cap)
	  end
	  last_end = e+1
	  s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
	  cap = pString:sub(last_end)
	  table.insert(Table, cap)
   end
   return Table
end


init()
while true do
event,parm1,parm2,parm3,parm4=os.pullEvent("modem_message")
words=split(parm4,"\°")
T1=words[1]
T2=words[2]
WS=words[3]
A=words[4]
B=words[5]
C=words[6]
team1=words[7]
team2=words[8]
fillTable()
screen()
end

Players1
Spoiler

function init()
modem=peripheral.wrap("back")
modem.open(3)
monitor=peripheral.wrap("top")
button={}
players={}
monitor.setBackgroundColor(colors.black)
monitor.setTextScale(1)
monitor.setTextColor(colors.white)
team="Green"
color=colors.green
fillTable()
screen()
end

function setTable(name, text, x, y, color)
  button[name] = {}
button[name]["color"] = color
  button[name]["x"] = x
  button[name]["y"] = y
button[name]["text"] = text
end

function fillTable()
i=3
button={}
setTable("title",team.." players", 1, 1,color)
setTable("title2","Kil Dea", 12, 2,colors.black)
for name,data in pairs(players) do
setTable(i,name, 1, i,colors.black)
setTable(i.."kills",data.kills, 12, i,colors.black)
setTable(i.."deaths",data.deaths, 16, i,colors.black)
i=i+1
end

end	

function fill(text, color, bData)
monitor.setBackgroundColor(color)
monitor.setCursorPos(bData["x"], bData["y"])
monitor.write(text)
monitor.setBackgroundColor(colors.black)
end

function screen()
monitor.clear()
  for name,data in pairs(button) do
	fill(data.text, data.color, data)
  end
end

function split(pString, pPattern)
   local Table = {}
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
	  if s ~= 1 or cap ~= "" then
	 table.insert(Table,cap)
	  end
	  last_end = e+1
	  s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
	  cap = pString:sub(last_end)
	  table.insert(Table, cap)
   end
   return Table
end

function player(name, state, kills, deaths)
if state=="add" then
players[name]={}
players[name].kills="0"
players[name].deaths="0"
end
if state=="update" then
players[name].kills=kills
players[name].deaths=deaths
end
if state=="remove" then
players[name]=nill
end
end

init()
while true do
event,parm1,parm2,parm3,parm4=os.pullEvent("modem_message")
words=split(parm4,"\°")
name=words[1]
state=words[2]
kills=words[3]
deaths=words[4]
if state=="team" then
team=name
elseif state=="clear" then
players={}
else
player(name, state, kills, deaths)
end
fillTable()
screen()
end


Players2
Spoiler

function init()
modem=peripheral.wrap("back")
modem.open(4)
monitor=peripheral.wrap("top")
button={}
players={}
monitor.setBackgroundColor(colors.black)
monitor.setTextScale(1)
monitor.setTextColor(colors.white)
team="Blue"
color=colors.blue
fillTable()
screen()
end

function setTable(name, text, x, y, color)
  button[name] = {}
button[name]["color"] = color
  button[name]["x"] = x
  button[name]["y"] = y
button[name]["text"] = text
end

function fillTable()
i=3
button={}
setTable("title",team.." players", 1, 1,color)
setTable("title2","Kil Dea", 12, 2,colors.black)
for name,data in pairs(players) do
setTable(i,name, 1, i,colors.black)
setTable(i.."kills",data.kills, 12, i,colors.black)
setTable(i.."deaths",data.deaths, 16, i,colors.black)
i=i+1
end

end	

function fill(text, color, bData)
monitor.setBackgroundColor(color)
monitor.setCursorPos(bData["x"], bData["y"])
monitor.write(text)
monitor.setBackgroundColor(colors.black)
end

function screen()
monitor.clear()
  for name,data in pairs(button) do
	fill(data.text, data.color, data)
  end
end

function split(pString, pPattern)
   local Table = {}
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
	  if s ~= 1 or cap ~= "" then
	 table.insert(Table,cap)
	  end
	  last_end = e+1
	  s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
	  cap = pString:sub(last_end)
	  table.insert(Table, cap)
   end
   return Table
end

function player(name, state, kills, deaths)
if state=="add" then
players[name]={}
players[name].kills="0"
players[name].deaths="0"
end
if state=="update" then
players[name].kills=kills
players[name].deaths=deaths
end
if state=="remove" then
players[name]=nill
end
end

init()
while true do
event,parm1,parm2,parm3,parm4=os.pullEvent("modem_message")
words=split(parm4,"\°")
name=words[1]
state=words[2]
kills=words[3]
deaths=words[4]
if state=="team" then
team=name
elseif state=="clear" then
players={}
else
player(name, state, kills, deaths)
end
fillTable()
screen()
end
Edited by
Lyqyd #2
Posted 19 June 2013 - 01:21 PM
Split into new topic.

Essentially, you should declare a couple of new variables at the top: canChat and chatLines. canChat will be a boolean that is true when we can send out a chat message immediately and false if we are waiting for a timer. Then, any time you would send out a chat message, you check canChat. If it's true, you send out the message, set canChat to false, and start a timer. If canChat is still false when the next message would be sent, you instead put the message into the chatLines table with table.insert. In your main loop, you add a handler for timer events (this will handle the timer that we start whenever we send out a chat message). Whenever a timer event comes in, it looks at the chatLines table. If there's anything in it (#chatLines > 0), it uses table.remove(1) to remove the first entry from the table (table.remove returns the value of the entry it removed) and sends it out as a chat message. It leaves canChat false and starts another timer. If the chatLines table was empty when the timer event was received, we simply set canChat to true again.

This is going to be a much more robust solution than re-queuing events. One should never re-queue events that have already come in, as other coroutines will not know that the event is a duplicate and will treat it as a new event.
timikx #3
Posted 19 June 2013 - 01:47 PM
Thank you,
I didn't think about it like that. I will try to do it your way.
Thanks again