PtokaX forum

Archive => Archived 4.0 boards => Help with Lua 4 scripts => Topic started by: chaggydawg on 30 April, 2004, 14:14:23

Title: Pausing before command
Post by: chaggydawg on 30 April, 2004, 14:14:23
Is there anyway without using a OnTimer()   to pause for a certain amount of time before executing a command. I'm sure many people have had this problem:

curUser:SendData(Botname.." You are being disconnected")
curUser:Disconnect()


the user never recieves the message before disconnection....

I need some sort of

curUser:SendData(Botname.." You are being disconnected")
(PAUSE HERE FOR A SECOND OR TWO)
curUser:Disconnect()

kind of deal, but without using a timer...

Any ideas guys?
Title:
Post by: nErBoS on 30 April, 2004, 14:55:12
Hi,

Well the user is not reciving the message because this is wrong..

curUser:SendData(Botname.." You are being disconnected")
should be...

curUser:SendData(Botname, " You are being disconnected")
Best regards, nErBoS
Title:
Post by: chill on 30 April, 2004, 14:58:22
uses the cpu i guess.

function f()

curUser:SendData(Botname.." You are being disconnected")

--(PAUSE HERE FOR A SECOND OR TWO)
Sleep(1)

curUser:Disconnect()
end



function Sleep(sec)
sec = sec*1000
local t1 = clock()
while clock() < t1+sec do
--sleep
end
end

but else I don't have that sort of problem with ptokax
Title:
Post by: chaggydawg on 30 April, 2004, 14:58:38
wouldn't that be for curUser:SendPM      ??

curUser:SendPM(BotName,"message")
curUser:SendData(data)



but anyways that was just an example, I've tried all sort, including SendToAll, and still the person is disconnected way to fast to recieve the data...
Title:
Post by: chaggydawg on 30 April, 2004, 15:00:02
Thanx chill I'll give that a shot  :)
Title:
Post by: chill on 30 April, 2004, 15:05:07
no prob, and tell me about the cpu usage if you have time :)
Title:
Post by: chaggydawg on 30 April, 2004, 15:08:27
seems it just froze the hub lol
Title:
Post by: chaggydawg on 30 April, 2004, 15:10:07
Perhaps because I am using it during userlogin process, and the hub is waiting for further data or something, I waited about 2 minutes before I closed to see if maybe it just needed to timeout... but no luck there
Title:
Post by: chaggydawg on 30 April, 2004, 15:16:14
ok I did:

t1 = clock()
SendToAll(botname,t1)



in the dataarrival, and I think maybe 1000 was just to high of a number to use hehe, doesn't seem to be milliseconds but seconds

crazybot> 393.366
[09:12] 413.615
[09:13] 419.574
[09:13] 424.481
[09:13] 428.697
[09:13] 436.748
[09:13] 444.449
[09:13] 447.844
[09:13] 448.495
[09:13] 448.495
[09:13] 451.179
[09:13] 465.069


So I'm gonna try again with a much lower number
Title:
Post by: chaggydawg on 30 April, 2004, 15:21:14
yah using a number like 3 is better, it pauses for 3 seconds than continues, CPU usages shoots up to about 60% (atleast on my PC)  while its waiting however, but drops right back down afterward.
Title:
Post by: chaggydawg on 30 April, 2004, 15:31:27
ok this worked perfectly thank you very much chill   :)


Here the chunk I used it in, I did .2 seconds, and it worked fine

elseif ( tonumber(ccTag["V"]) < tonumber(AllowedClientVersions[ccClient]) ) then
curUser:SendData("<"..secbot..">    You Must Upgrade Your Client To Atleast "..ccClient.." v"..AllowedClientVersions[ccClient])
local t1 = clock()
while clock() < t1+.2 do
--sleep
end
curUser:Disconnect()
end

Title:
Post by: chill on 30 April, 2004, 18:57:22
great but it uses a lot of cpu :(.
and yepp if thaught cpu time was in milliseconds. maybe use a timer,

function Main()

doLater(2,function() SendToAll("test") end)

end

todoLater = {}

function doLater(sleep,func)
todoLater = func
SetTimer(sleep*1000)
StartTimer()
end

function OnTimer()
todoLater()
StopTimer()
end

but, when you want to pass on something like curUser:f(), I guess you would need to access curUser, afterwards, over a table.
Title:
Post by: chill on 30 April, 2004, 19:10:25
bit more advanced :)


function Main()

SetTimer(1000)
StartTimer()

doLater(2,function() SendToAll("test 2") end)
doLater(5,function() SendToAll("test 5") end)
end

todoLater = {}

function doLater(sleep,func)
tinsert(todoLater,{ sleep,0,func })
end

function OnTimer()
foreach(todoLater, function(i,v)
if (i ~= "n") then
v[2] = v[2] + 1
if v[2] == v[1] then
v[3]()
tremove(todoLater,i)
end
end
end)
end
Title:
Post by: Corayzon on 02 May, 2004, 11:14:22
yea...thats what i was thinking...in a way...but with some asserting n shit

more like...adding the command to a table with the fields...toWait, Commands, ArgList...

and on the timer...count down the toWait feild...and when lower then 0 dostring will do the trick ;)
Title:
Post by: chaggydawg on 02 May, 2004, 11:18:56
Just when i think i'm starting to know things... I come here and feel stupid all over again   lol
Title:
Post by: chill on 02 May, 2004, 12:36:27
lol chaggydawg, same here :)

Corayzon, yepp optimised it a bit

function Main()

curUser = GetItemByName("dumbo")
doLater(7,{curUser},
function(table)
table[1]:Disconnect()
end)
doLater(2,{},function() SendToAll("test 2") end)
doLater(5,{},function() SendToAll("test 5") end)
doLater(6,{},function() SendToAll("1 sec till disconnect") end)
end

todoLater = {}

function doLater(sleep,tvar,func)
tinsert(todoLater,{ sleep,tvar,func })
end

function OnTimer()
foreach(todoLater, function(i,v)
if (i ~= "n") then
v[1] = v[1] - 1
if v[1] == 0 then
v[3](v[2])
tremove(todoLater,i)
end
end
end)
end
Title:
Post by: chill on 02 May, 2004, 12:40:54
just another exsample, with more variables
function Main()


local string = "Dunno"

curUser = GetItemByName("dumbo")

-- curUser will be table[1] in func and string table[2]
doLater(2,{curUser,string},
function(table)
table[1]:SendData(table[2])
end)

doLater(7,{curUser},
function(table)
table[1]:Disconnect()
end)
doLater(2,{},function() SendToAll("test 2") end)
doLater(5,{},function() SendToAll("test 5") end)
doLater(6,{},function() SendToAll("1 sec till disconnect") end)
end

todoLater = {}

function doLater(sleep,tvar,func)
tinsert(todoLater,{ sleep,tvar,func })
end

function OnTimer()
foreach(todoLater, function(i,v)
if (i ~= "n") then
v[1] = v[1] - 1
if v[1] == 0 then
v[3](v[2])
tremove(todoLater,i)
end
end
end)
end
Title:
Post by: Corayzon on 02 May, 2004, 14:02:16
yea...thats kinda what im talkin bout...

but dont u find it a little hard to read?
Title:
Post by: chill on 02 May, 2004, 20:21:50
hmm.. nope think its as simple as can be :), but show me what you had in mind :).
Title:
Post by: Corayzon on 03 May, 2004, 03:48:42
just this

function OnTimer()
foreach(todoLater, function(i,v)
if (i ~= "n") then
v[1] = v[1] - 1
if v[1] == 0 then
v[3](v[2])
tremove(todoLater,i)
end
end
end)
end

i guess its not that bad...its just i dont understand exactly whats kicks ere...and i say that cause
its writin bad...u should rename i,v into names that show u what they mean

and i work with tables and arrays alot dif...as u prob can tell...ill write up my version sometime soon and then post it ere ;)
Title:
Post by: NotRabidWombat on 04 May, 2004, 05:29:05
chill,

You can make that script a lot more versatile with the call function:

call (func, arg [, mode [, errhandler]])
Calls function func with the arguments given by the table arg. The call is equivalent to

       func(arg[1], arg[2], ..., arg[n])
where n is the result of getn(arg) (see Section 6.1). All results from func are simply returned by call.

http://www.lua.org/manual/4.0/manual.html

If you do that it would be much more efficient to pass a reference to functions rather than creating a new one for each event.

-NotRabidWombat
Title:
Post by: chill on 04 May, 2004, 18:29:05
dunno if this is how you meant it, but also a way I'd say
gotta check the options, cause can I like also get it to only store the function inclusive arguments?


curUser..
string = "2 sec"

-- exsample code
doLater(2,{curUser,string},
function(curUser,string)
curUser:SendData(string)
end)


todoLater = {}

function doLater(sleep,tvar,func)
tinsert(todoLater,{ sleep,tvar,func })
end

function OnTimer()
foreach(todoLater, function(i,v)
if (i ~= "n") then
v[1] = v[1] - 1
if v[1] == 0 then
call(v[3],v[2])
tremove(todoLater,i)
end
end
end)
end
Title:
Post by: ??????Hawk?????? on 04 May, 2004, 19:35:40
hi peeps :-)


any chance of developing something in line with the  origional request  ???


QuoteIs there anyway without using a OnTimer()  to pause for a certain amount of time before executing a command. I'm sure many people have had this problem:

im still reletavely new to  Lua, and still learning.  but could  make use of this function ..
Title:
Post by: NotRabidWombat on 04 May, 2004, 23:31:04
Not without understanding the threading of API calls through PtokaX.

OnTimer is the only real way to delay events. It's not a bad way either. Why not use it?

-NotRabidWombat
Title:
Post by: Corayzon on 05 May, 2004, 05:46:37
i been thinking hard bout this one...

you guys know how in some scripts the connection\disconnection methods can take a long time to process and they hold up the hub until they are...

well im thinking of something as follows...

u guys prob know bout in process components and out of process components...wellz here is the idea...

on the connection methods, you could delay the command with a timer, then when the command is called pass it as a out of process method so then when it executes it doesnt hold up the server process

is this possable???

thankz to the smarty pants that answers this one in advance =]
Title:
Post by: NotRabidWombat on 05 May, 2004, 06:44:04
"you guys know how in some scripts the connection\disconnection methods can take a long time to process and they hold up the hub until they are"

We can't really make these assumptions without knowing more about the socket communication used by PtokaX, specifically assync vs sync.

Anyway, I'm not really sure you would see benifits to moving communication calls out of OnConnect, OnDisconnect. I *believe* these commands do not block and add the message to an out going queue. So no matter where you call them, any communication occuring after them will have to wait.

I also *believe* Disconnect does not do any kind of queuing and just kills the socket. This would explain the problem that started this thread.

-NotRabidWombat
Title:
Post by: Corayzon on 05 May, 2004, 07:07:00
sorry u seem to have taken me wrong...

example::

you have

function connect(user)

end

now when u add some code like

function connect(user)

saveuserinfo(user)
inoutmsg(user)
checkbanned(user)

end

this will be executed like...

connect called...
process savesuerinfo and when function is done then
process inoutmsg and when function is done then
process checkbanned and when function is done then
then end function

what im thinkin is this...

is taking out an ordered process from it...

so...

function connect(user)

doLater(saveuserinfo(user))
inoutmsg(user)
doLater(checkbanned(user))

end

when the user connects ... he is allowed to connect strait away...not holding up the process,,, and then the other commands that were called in the connect function execute later...but also as a out of process component...meaning while the commands process...the rest f the server isnt help up by it

u get me?
Title:
Post by: NotRabidWombat on 05 May, 2004, 07:19:42
Well, I'm assuming that the functions inside of the OnConnect *need* to happen right then. Such as the checkbanneduser. If the user is banned, you really do not want them communicating with the hub.
Likewise, serializing table information should be taken care of in the next release with the OnExit command. Then saving periodically in case of a crash becomes the issue.

I forsee the DoLater concept being most effective when dealing with socket communications since only syncronous is allowed through lua right now.

-NotRabidWombat
Title:
Post by: Corayzon on 05 May, 2004, 07:55:41
wells this is just an example and doesnt apply to anything...

i just wanted to show that i want to be able to process to commands at the same time...but not have one held up by the other...

i guess i cant explain...but in vb...its 'in process' and 'out process'...if u understand that...then ull understand what im asking

aswell as what im asking cant be proformed via a function cause the preprocessor needs a return to move out of a function and continue the process...if that makes any sense
Title:
Post by: NotRabidWombat on 05 May, 2004, 16:47:06
I understand what you are asking. You want a form of multithreading.

However, I can not imagine any function in the OnConnect or OnDisconnect that does not change the state of an object. If you're changing the state of an object with multiple threads you must ensure they do not change the object at the same time. This is called thread safety. So these statements will end up stopping each other anyway, defeating the purpose of having multiple threads.

-NotRabidWombat
Title:
Post by: Corayzon on 06 May, 2004, 02:07:02
i see...but if this was implemented and done right, could this stop the amounts of lag sometimes made by functions reading through large files?

aswell as...what bout havein a database like this...cause most of these hold ups are from file reading and record replacing...

thankz