Skip to content

Change computer.beep() to be non-blocking system-wide #3789

@ReallySecureShell

Description

@ReallySecureShell

OpenComputers Mod Version: 1.8.9a for Minecraft 1.12.2
OpenOS version of test system: OpenOS 1.8.8
LUA Version: Lua 5.3

As discussed in issue #1112 computer.beep() is a blocking call. On OpenComputers version 1.8.9a computer.beep() will block all execution on the computer until the call completes, including if computer.beep() was called from a detached thread.

I would appreciate it if instead of computer.beep() blocking execution system-wide, calling it only blocks within the thread it was executed from. The consequence of this change would enable users to have multiple instances of computer.beep() running concurrently using threads, which I believe would be an improvement to the current system.

I understand that the Computronics mod by Vexatos adds a beepcard that is non-blocking. However, the behavior of computer.beep() in the mainline mod should still be changed so that it at least does not block execution system-wide.

The following example code shows computer.beep() blocking execution of the main program thread while it runs within the detached thread:

local computer = require("computer")
local event    = require("event")
local thread   = require("thread")

local play_audio_tone = thread.create(function(tone_id)
  -- tone 1
  -- 340Hz 500ms on, 500ms off Intermittent
  local function tone1()
    local t = 0

    for i = 1, 4 do
      if (i % 2) == 1 then
        computer.beep(340, 0.50)
      else
        t = computer.uptime()
        repeat os.sleep(0) until( ( computer.uptime() - t ) >= 0.50 )
      end
    end
    computer.pushSignal("tone_complete", 1)
  end

  local PLAY_TONES = {
    [1] = function() tone1() end
  }

  -- crude system for picking which audio tone to play for testing using args passed from shell
  if type(tone_id) == "number" and tone_id > 0 and tone_id <= 8 then
    --event.timer(1, PLAY_TONES[tone_id)
    PLAY_TONES[tone_id]()
  else
    print("Invalid argument")
  end

  while true do
    local event, param1 = event.pullMultiple("interrupted", "tone_complete")

    if event == "interrupted" then
      print("interrupted")
      break
    elseif event == "tone_complete" then
      PLAY_TONES[param1]()
    end
  end
end, 1):detach()

local iter = 0

while true do
  os.sleep(1)
  print(iter)
  iter = iter + 1
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions