Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
  • 0
CosmoConsole

Waiting for an undetermined time in a callback

Question

I'm trying to implement OpenComputers support for a mod I'm making. The mod in question already supports ComputerCraft. I've managed to add OC support for everything else save for a radio transmitter block.

The block / tile entity in question is designed to allow sending data over a channel, but is restricted to sending a certain amount of data within a timeframe. To be exact, you can send 2205 bytes over a channel 5 times a second (0.2 seconds per packet).

To this end, the transmission method for ComputerCraft waits a certain amount of time if data has already been sent:

			if (PhotonicRadio.sendCache.containsKey(channel)) {
				PhotonicRadio.sendEventWhenSend(computer);
				context.pullEvent("photoniccraft_sendtimer");
			}

sendCache is whether data has already been sent to a certain channel, and sendEventWhenSend adds the computer into a queue, after which the thread responsible for running the radio (as well as sending packets to players; there's a pocket radio item to play the radio data as audio). The queue is cleared on every send by sending an event to all of the computers in the queue, and the pullEvent function will block until this event is sent - which makes the computer idle and wait until the packet currently in the queue is sent.

For OpenComputers, I've failed to find such an alternative. I'm aware of Context#pause, but it requires a specific determined amount of time to pause for - and while the radio thread is supposed to be run every 200 ms as timed by the server scheduler, I cannot be certain that estimating the time would be correct - if it's too early, the whole thing may break apart, while if it's too late, it wastes processing time on the computer.

I was thinking of using direct = true and simply using semaphores - adding the semaphore into the same radio queue, waiting it (acquire) and then signaling it (release) in the radio thread, but this actually causes the entire server to lag - if I add a print statement into the callback, 9 out of 10 calls still come directly from the server thread, so forcing it to sleep causes everything else to stop as well.

I have noticed Machine#popSignal, but I'm not certain how to retrieve a Machine instance from a ManagedEnvironment, and it doesn't seem popSignal is blocking anyway ("return a signal or null if the queue was empty").

Is there any better way to achieve what I'm trying to do other than spinning (check if we've sent a packet, if not, Context#pause and check again), which feels wasteful?

edit: It seems that using Context.pause and spinning causes all other computers to slow down (even if I try to predict the time beforehand and spin afterwards if it isn't sufficient), which makes a better solution (that could yield) even more urgent.

Edited by CosmoConsole
updated
Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0
2 hours ago, Molinko said:

I personally have no idea but I think you can get the help you need in the #oc Discord channel.

Are the forums basically inactive with everyone choosing to hang around Discord instead? Mostly asking for whether I have a chance of getting the answer here or if I should somehow get on there to ask this.

Link to post
Share on other sites
  • 0

The forums are more for coding in game in Lua. At least that the most responsive part of the community in the forum. Many of the maintainers of opencomputers and companion mods hang out in the discord and irc chat regularly. Be patient with them.

Link to post
Share on other sites
  • 0
10 hours ago, Molinko said:

The forums are more for coding in game in Lua. At least that the most responsive part of the community in the forum. Many of the maintainers of opencomputers and companion mods hang out in the discord and irc chat regularly. Be patient with them.

Thank you for the tip, I'll be trying IRC or Discord soon. I'll mark this thread as solved once I get a satisfactory solution.

Link to post
Share on other sites
  • 0

I don't think this is possible and I also don't know why you want to pause the computer for that. I think its better if you enforce the limit by returning false or throw an error. But by pausing the computer it will not be able to handle other events like network or touch events. So this would not make much sense.

Link to post
Share on other sites
  • 0
25 minutes ago, feldim2425 said:

I don't think this is possible and I also don't know why you want to pause the computer for that. I think its better if you enforce the limit by returning false or throw an error. But by pausing the computer it will not be able to handle other events like network or touch events. So this would not make much sense.

I don't need to pause the computer but to rather pause the execution of the program (something that event.pull in Lua can do). Returning false or throwing an error is a bit of a breaking API change and differs from the ComputerCraft approach, so I'd prefer to not use it. However, it could be a good idea to send a signal either way to allow catching it, but I'd still need to enforce the limit by waiting a certain amount of time in the callback.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.