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

Redlogic Api - Not Just Gates

Started by acesoyster, 23 July 2013 - 04:31 PM
acesoyster #1
Posted 23 July 2013 - 06:31 PM
I've been holding this back a while, because it's by no means finished and I'm a tad nervous about my first contribution to the community, but I'm pleased to finally show you my current project…

The RedLogic API


I first got into ComputerCraft because I thought it'd be a quick way to quickly test out redstone logic on a large scale, before going to the effort of trying to mash vanilla gate designs together. I was therefore a bit sad when I found relatively little already programmed. Many people seem to have started projects, but then seemingly never gone back to them. The coding for these sorts of things was never going to be too difficult for a newbie, and so I gave it a crack.

The functions are described in the API code, but I am yet to write a getFunctions function. Sorry about that, but I ought to have that done tomorrow afternoon.

So far, my current list of functions is:

Simple
  • Gates: And, Implies, Not Implies, Or, Nand, Nor, Xor, XNor
  • Full binary adder
Memory
  • D Flip Flop
  • D Latch
  • JK Flip Flop
  • RS Latch
  • T Flip Flop
  • Clock
  • Sequencer (Not like what RedPower calls a sequencer, has variable time for each output state, and can be programmed to an infinitely long sequence)
Pulse Logic
  • Monostable Circuit
  • Pulse Lengthener (Takes a definite pulse as input and multiplies that pulse in the output)
  • Pulse Length Detector
  • Repeater (If anyone can think of a way of getting this down to zero delay, I'd be very grateful)
  • Simple Delay
  • Advanced Delay (Can listen to a sequence of pulses and repeats them, even if they are shorter than the delay time)
  • Randomizer (Outputs to any side with variable weighting)
  • Noise Generator (Outputs pulses at random intervals, between limits)
  • Counter
Transmission
  • Multiplexer
  • Synchronizer (As a Brit, it pains me to spell that with a Z, but what can a man do?)
  • Wireless Send
  • Wireless Receive
Analog
  • Analog Add
  • Analog Subtract
  • Analog Not Gate
Pastebin Code: h7DDhXDd

The plan from here is to finish off the analog logic, get this code tidy and documented, and then work on showcasing some of the things I've done with this API. Also, can someone give me a good use of the state cell, invert cell, etc. from RP2? I was considering coding them but came to the decision that as I have never once used them, I'd wait and see if there were any demand.

Also, can anyone advise me on how to have two different references for an API, like the redstone API has redstone. and rs.? Thanks!

I am not an experienced coder, and I've learnt a lot over this project. Therefore, if there are some poor choices made near the top of the API, please forgive me. Any advance, bug reports, or criticisms would be appreciated. i'm going to university in September to study electronic engineering, and coding is something I am really not prepared for. Any general tips would be help me a lot.


Thanks again :)/>
Zudo #2
Posted 24 July 2013 - 01:43 AM
It looks great!

You can't have two different references unless you have an "API loading" script like this:


os.loadAPI("redlogic")
rl = redlogic

that you run to load the api.
bentallea #3
Posted 23 August 2013 - 01:10 AM
you could have 2 references if you save the api as both names, redlogic and rl. and have you tried sleep(0) for the 0 tick delay?
acesoyster #4
Posted 26 August 2013 - 06:54 AM
It looks like using sleep(0) gives the same delay as using events.
theoriginalbit #5
Posted 26 August 2013 - 07:21 AM
Also, can anyone advise me on how to have two different references for an API, like the redstone API has redstone. and rs.? Thanks!
The easiest method… at the very end of the file


--# create the secondary table
_G.otherId = {}

--# get the current file's environment
local env = getfenv()
--# loop the environment
for k,v in pairs( env ) do
  --# add the function's into the other table
  _G.otherId[k] = v
end
However you need to be mindful that the main API will be whatever they name the file…. the secondary one that you make is whatever you give it.

It looks like using sleep(0) gives the same delay as using events.
Depends on the event stack size, it can be considerably slower!
BigTwisty #6
Posted 09 September 2013 - 05:22 PM
I was under the impression that sleep(n) just started an os timer and then held up the system until it received the clock event, like this:

function sleep(n)
  t = os.startTimer(n)
  repeat
    _,a = os.pullEvent("timer")
  until a == t
end

Wouldn't sleep(0) just clear out all buffered events and then continue right away? Or is there some special case it applies when given 0?
theoriginalbit #7
Posted 09 September 2013 - 07:24 PM
I was under the impression that sleep(n) just started an os timer and then held up the system until it received the clock event, like this:

function sleep(n)
  t = os.startTimer(n)
  repeat
	_,a = os.pullEvent("timer")
  until a == t
end

Wouldn't sleep(0) just clear out all buffered events and then continue right away? Or is there some special case it applies when given 0?
Yes that is precisely what sleep does, here is the actual code

function sleep( _nTime )
  local timer = os.startTimer( _nTime )
  repeat
	local sEvent, param = os.pullEvent( "timer" )
  until param == timer
end
So yes it clears the event queue.

However to prove what I was saying, and so you can see the results for yourself, here is a test script… (it should be noted that the event queue would only have the timer event in it)

local function test(func, t)
  print("Testing: "..t)
  local start = os.clock()
  for i = 1, 500 do func(0) end
  print("Duration: "..(os.clock() - start))
end
test(function() os.queueEvent('d') coroutine.yield('d') end, "yield specific")
test(function() os.queueEvent('d') coroutine.yield() end, "yield generic")
test(function() os.queueEvent('d') os.pullEventRaw('d') end, "pullEventRaw specific")
test(function() os.queueEvent('d') os.pullEventRaw() end, "pullEventRaw generic")
test(function() os.queueEvent('d') os.pullEvent('d') end, "pullEvent specific")
test(function() os.queueEvent('d') os.pullEvent() end, "pullEvent generic")
test(sleep, "sleep")