ID:152325
 
Suppose a message is sent to the user from a process. I want the process to "pause" and then continue after receiving a response from the user.

For example:

mob/proc/Myproc()
src << "Hello user"
//wait for response"
src << "Thank you for responding"

mob/verb/Hi()
src << "Hello computer"


I'd want it to display "Hello user" first, then wait for the user to use the Hi() verb. Once they use it, I then want the process to continue and display "Thank you for responding".

I know I can use this sort of method:

while(waiting_for_response)
sleep(1)


But I'd like something better.

Alternatively I could use 2 procs, one to ask for a response and one called after getting the response. I can't really do this since I'll want more than a hundred responses per process.
mob/proc/Myproc()
src << "Hello user"
if(mob.response = 1)
src << "Thank you for responding"
mob/var/response = 0
verb/Hi()
src << "Hello Computer"
response = 1


You could do something like that. Im not sure if the code is right but im sure some expert coder could fix it up. (Im pretty bad at coding and i dont really understand how to set up if statements...)
In response to FretFulGun
That's not really right since it's not pausing, the if() check only lasts for a second (actually less than a second) and then the process continues.
You could try an event buffer and treat your game like a multi-threaded application. When you receive a proc that waits for an event, just sit and wait in the proc using a while loop like the following:

while(src.MadeResponse(/response/Clicked_OK) != 1)
sleep(1)


and then when the player clicks the "OK" verb, it simply pushes that response onto the event buffer.

  event_buffer += /response/Clicked_OK


and your MadeResponse() procedure would then meet that condition, remove that event from the buffer, and continue. For safety, you'll also want to discard events that the player isn't allowed to use at the time, just to prevent them from remaining in the buffer and triggering at some unpredictable moment for no explicable reason, and for safety you should clear the buffer entirely (event_buffer = list()) after completing significant tasks.
In response to Abhishake
damn, didnt notice that lol.. maybe add a ..() after it so it repeats itself a billion times until so? I wouldnt know :P
I don't think there's any way of doing that short of busy-waiting.
In response to Jp
mob/proc/Myproc()
src << "Hello user"
if(mob.response = 1)
src << "Thank you for responding"
else
..()
mob/var/response = 0
verb/Hi()
src << "Hello Computer"
response = 1


I don't know if that would just spam the src with "Hello user" or not. If I were you I would just keep trying stuff. Or use the other stuff suggeseted.
In response to FretFulGun
That won't do anything. You're defing the procedure there, so it obviously doesn't have a parent procedure to return to. Please don't try and give out programming help if you don't know how to program or if you don't know what you're talking about.
Abhishake wrote:
Suppose a message is sent to the user from a process. I want the process to "pause" and then continue after receiving a response from the user.

Since there is really no internal functionality for this sort of thing, my best guess at a method would be to stop one process, and start another after the response.

I know I can use this sort of method:

> while(waiting_for_response)
> sleep(1)
>

But I'd like something better.

Most definitely. At best, that's an easy way to eat a CPU up, and I would never recommend that kind of usage.

Alternatively I could use 2 procs, one to ask for a response and one called after getting the response. I can't really do this since I'll want more than a hundred responses per process.

Indeed, it does seem to be somewhat of a challenge to merely handle responses with a toggle-variable---imagine how many separate variables you might use, and how you might manage them! However, my first thought to solve this was to encapsulate these events into objects, and each event would handle its own before and after functionality. With variables that belong to the event, each datum could save its state between calls to each proc. The player would keep a reference list of "active" events, and de-activate them as specific conditions are met. For example:
/*
The /Event datum will have two defined procs (extensible, of course!).
When a new /Event is created, it will call the PreAction() proc. Before
being deleted, it will call the PostAction() proc. The way this system will
work is that it will store an /Event in an "events" list for the client.
When a condition is met to end an event, the program will check to see if there
is an event waiting to be released, and if so the event will be removed from the
events list (and automatically deleted by the garbage collector), causing the
PostAction() proc to be called.
*/


Event
var/client/owner

New(loc, client/C)
owner = C
PreAction()

Del()
PostAction()
..()

proc
PreAction()
PostAction()

EventA
var/myCt = 0

PreAction()
var/global/count = 0
myCt = ++count

owner << "You have started an event (#[myCt]). Please respond."

PostAction()
owner << "You have responded to an event (#[myCt]). Process continues here."


client/var/list/events = new

client/verb
verb1()
set name = "Get Message"
events += new/Event/EventA(null, src)

verb2()
set name = "Respond"
var/Event/EventA/event = locate() in events
if(event)
events -= event
else
src << "Nothing to respond to!"


That is a fairly simplified version of what one may actually use in practice, and I could imagine that as being fairly extensible.

Hiead
I agree with Jp. Short of what you said, I don't think there is any other distinct method.
And note that there already was a topic like this (not that there was any 3rd method there IIRC I'm afraid :p).
In response to Hiead
Just a quick note, /Event isn't even an atom so you don't need to workaround or even think about new/New()'s first arg being the loc.
In response to Kaioken
Kaioken wrote:
Just a quick note, /Event isn't even an atom so you don't need to workaround or even think about new/New()'s first arg being the loc.

This much I know. For some reason, I've just had the habit of using that first argument as such, even with datums, for a while now. I know quite well that datums don't even get map locations, but it just reads clearer to me that way, for some reason. =/ I suppose if you really wanted to, it could be taken out, but meh.

Hiead
In response to FretFulGun
Uh, no. ..() doesn't make whatever is in the if() statement repeat. If you changed if() to while(), THEN it'd repeat. But he said he doesn't want it to loop millions of times.
For processes like that, I used to use a datum to hold all of the data I needed and I defined the procedure under that datum. When I made a call to a procedure to handle responses, I'd have it perform the needed task. So, when I tell it to pause, it records the data and stops the procedure. When I tell it to unpause, it starts up the procedure at where it left off.

This does require the use of while(), but I don't doubt that you're already using one if you need to pause something. Great thing is that you don't need to use while() sleep() sort of statement.
In response to Exophus
Doesn't the input command stop the procedure until it get's input?
mob
verb
get_response()
var/response=input("Please respond") in list("Ok.","No!")
if(response=="No!")
src<<"Your penalty for not responding is this:"
src<<"Good bye."
sleep(10)
del src
return
src<<"Thank you for responding. Have a nice day!"
In response to Speedro
Yes, but did you think the solution to this is that obvious and we've all missed it? The issue here is pausing until some kind of different input/response is received, not by the built-in means like alert() and input().
In response to Kaioken
sleep_offline var (world)
Default value:
0
Setting this to 1 causes the world to be suspended when there are no players, even if you have sleeping procs waiting to happen. The default value is 0, which means the server will only sleep if there are no players and no procs waiting to happen. The main purpose of the variable is to save the cpu from doing work when there is nobody around to appreciate it. On the other hand, that doesn't give the poor NPC's a break from the nasty humans.


Does that fit into this category :(?
In response to A.T.H.K
Well, um, no... this is about deliberately pausing a proc until some response/event has happened, regardless of players.
That var just sleeps the whole server when there are no players to save CPU, which isn't really related to this.
In response to Kaioken
Well, there is that possiblility... I mean consider it: Is it possible to flip a coin and get heads every time for 6 million 8 hundred and 70 three times and then the next flip lands on the edge? Yes, it is but highley unlikely.

Anyways, your probably right, but there still always is that chance that you, Kaioken got a concussion and forgot what user input was, and everyone else who was answering got some sort of bizzare disease or something :)
In response to Speedro
Speedro wrote:
Well, there is that possiblility... I mean consider it: Is it possible to flip a coin and get heads every time for 6 million 8 hundred and 70 three times and then the next flip lands on the edge? Yes, it is but highley unlikely.

You consider human thinking as always having very random chances of success? :P The chance of 'thinking/picking up something correctly'/whatever isn't quite random by definition, and is much more complicated than one can explain in whole, of course.

Anyways, your probably right, but there still always is that chance that you, Kaioken got a concussion and forgot what user input was, and everyone else who was answering got some sort of bizzare disease or something :)

Lol, perhaps (..not :P), but I'm pretty sure that as further as you actually dive down this topic, it'll become more obvious that its about using more 'custom' means of input/respond than the built-in ones.
Page: 1 2