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

[WIP] [Utility] Automatic Peripheral Detection and Wrapping Script Called "Periscope", Variable Expansion Issues

Started by PixelPiranha, 28 May 2014 - 02:47 AM
PixelPiranha #1
Posted 28 May 2014 - 04:47 AM
Hello There!

I'm writing my first real, actually-does-stuff lua script (with perhaps too ambitious a goal), after almost 5 straight days of hardcore self-teaching; but I'm having an issue with what (I think) is the very last hurdle before Periscope is basically ready.

I'm attempting to make a script that will automatically detect all connected peripherals (through modem or no) and (based on task chosen) either display all detected peripherals(this part works) OR display one, and prompt the user for a variable name for the script to wrap that peripheral to; lather, rinse, repeat until all are wrapped…(this part doesn't quite work.)

Current Features:
“skip peripheral” function
very simple(and currently somewhat ineffective, for some reason) error detection
Two Modes:
display all detected
wrap detected one by one

Planned Features:(if I can get it working as is, lol)
already wrapped peripheral detection
cleaner instructional output (the print() statements everywhere aren't cutting it)

Symptoms:
everything works without even a single detected error, but when I go to the lua prompt to double-check if the entered variable names were wrapped properly they return nil values…

My Theory:
after some mindboogling, I think that the “name” arg to the “packagecandy” function (named as such because it “wraps”[c what i did thar? :P/> ]) isn't expanding to become the variable value, which should then be defined to [peripheral.wrap()]'s output; instead, it's staying as the literal string ”name”, which the peripherals are all getting wrapped to in turn…

Question:
how fix? That variable (should) contain the user's inputted wrapper name, but if it won't expand then how else can i get that input to become the peripheral.wrap() variable name? i've tried a few methods(commented in the code below), but lua complains about unexpected symbols…

All help offered is greatly appreciated; i'm quite proud of my progress so far, but now i'd just like for it to actually work! :D/>

So, without further ado, I present the mostly completed, yet thoroughly broken… Periscope!

Code So Far:
(p.s all my attempts to fix this issue are currently commented; as such, from lua's standpoint, the packagecandy function is currently empty… just a heads up for you, if you decide to test the code yourself.)

(p.p.s. please forgive the funky comment/code formatting; the code tags themselves are what's funkifying it tbh, as it's all perfectly lined up in both zerobrane, notepad++, and it even funkified when i manually lined it up in the posting WYSIWYG mods, feel free to edit that to fix it, as I've been trying for the past half hour using many combos of whitespace characters, with only what you see now to show for it.)



local tbl=peripheral.getNames() --detects peripherals
--local tbl ={"left", "logistics", "blokbreak", "right"}							  : zerobrane test code, ignore

function packagecandy(name, periph)												   -- function to wrap peripherals, called later on in script
	--name=peripheral.wrap('"'..periph..'"')										  -- attempt 1
	--tostring(name)=peripheral.wrap('"'..periph..'"')								-- attempt 2
	--string.format(name)=peripheral.wrap('"'..periph..'"')						   -- attempt 3
	--print(name .." :  ".. periph)												   -- more zerobrane remnants, ignore
end	

print("enter task to run")
print("valid tasks are: display, wrap")
print("input now")

local task=io.read()																  --allows user to select function to complete


if task == "display" then															 --this section reads what user wants, and does it ...
	print("printing all detected peripherals to screen, in order of table key")
	local display="true"
elseif task=="wrap" then
	print("beginning wrapping process")
	print("enter name for displayed peripheral, or \"skip\" to skip that peripheral")
else
	error("invalid task, please try again")										   -- or errors out if user uncooperative
end

for k,v in ipairs(tbl) do															 --parses peripheral table(not recursive since the tbl retreival never returns a nested table anyway[to my knowledge])
	if display=="true" then			
		print(k ..":   ".. v)														 --displays table if that option was selected
	else																			  -- or begins wrapping process otherwise
		print("now wrapping peripheral : ".. v)		
		print("designate wrapper, or skip")
		local wrapper = io.read()													 --user inputs wanted wrapper name, or "skip" to skip the listed peripheral
		if wrapper == "skip" then													 --"skip" detection
			print("skipping peripheral : ".. v)
		else																		  --calls wrapper function which wraps the listed peripheral name to the entered wrapper name
			print("wrapping peripheral : " ..v .. " : TO : ".. wrapper)
			local success=pcall(packagecandy, wrapper, v)
			if not success then													   --simple error detection
				error("wrapping failed! unknown reasons... try again?")
			else																	  --if no error detected, tell user that it went well!
				print("peripheral : " ..v .." : successfully wrapped TO : ".. wrapper)
			end
		end
	end
end
print("complete!")																	-- all done!


Thanks all!
CometWolf #2
Posted 28 May 2014 - 09:54 AM
This is a pretty pointless function to be honest. It'd make sense to display the peripheral functions and to be able to run them from the program. Wrapping them however is just silly. You'd have to run this program and wrap the peripheral prior to running your own.

There is however a way to do this if you really want to so badly.

_G[name] = peripheral.wrap(perip)
Thus storing the function table in the global environment, under whatever name is. You'd have to pass the name as a string though.
PixelPiranha #3
Posted 28 May 2014 - 12:22 PM
Hey There!

Thanks for the input! I'm glad that it can actually be implemented, at all; I was afraid that anything on that side of the equals sign when defining a variable would simply be taken as a string, no expansion allowed…

However, I’m not quite sure that I know what you mean by “pointless”; if by “displaying peripheral functions” you mean the functions of the Peripheral API itself, I actually agree, to a point. In hindsight, it is a bit “unversatile”, being limited simply to wrapping; allowing the script to pick a function from that API to complete based on user input would be a valuable addition/overhaul to the feature set (I still wouldn't quite say it's pointless as is, though, as it's a valuable timesaver and a good first step to testing out another [or any other] peripheral based script idea; not to mention I worked hard on that bugger! :P/> ). But if by that you mean to display all the methods of all detected peripherals, it's a bit out of scope, (or current author ability, for that matter, lol :P/> ); plus the output to the terminal would be quite ugly, if not entirely unreadable. However, as an easy setup tool, to quickly, efficiently and easily enable further testing of all peripherals connected, I think it's a good start.

It actually started out as merely an easy way to automatically wrap peripherals connected via wired modem, without going name hunting, and wrapping one by one; it grew into this from there as I got more and more carried away, and as stated before, I'm new to both Lua and Computercraft, so if there's an easier/better way, please, enlighten.

In either case, while I wrote this reply I reviewed the Peripheral API page on the wiki and I’m having trouble finding additional functions that look like a good fit… any ideas?

(p.s. my Computercraft install is based in Tekkit (forgot to mention that in my OP, my bad), and that's currently running CC 1.58; idea compatibility with that version would be greatly appreciated. It also includes OpenPeripheral, though, so that's a plus.)

Constructive criticism always welcome! :D/>
CometWolf #4
Posted 28 May 2014 - 03:35 PM
Well no, i was thinking of the latter :P/> So something like a menu with all the names of the connected peripherals, selected one, and it shows all the functions accesible to that peripheral. Then from there, be able to call said functions. Obviously the menu would have to be scrollable to avoid it being "ugly".