Jump to content




augustas656's read() replacement questions topic



  • You cannot reply to this topic
31 replies to this topic

#1 augustas656

  • Members
  • 158 posts

Posted 09 May 2014 - 10:49 PM

Regards
Augustas

#2 awsmazinggenius

  • Members
  • 930 posts
  • LocationCanada

Posted 09 May 2014 - 11:05 PM

Look in the APIs and bios.lua

#3 Yevano

  • Members
  • 376 posts
  • LocationUSA

Posted 09 May 2014 - 11:45 PM

Specifically, those files can be found inside your computercraft mod folder under assets\computercraft\lua\.

#4 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 10 May 2014 - 01:07 AM

because I'm feeling in quite a charitable mood today, here you go, write, print and read as of ComputerCraft 1.6x (iirc)

#5 augustas656

  • Members
  • 158 posts

Posted 11 May 2014 - 12:18 PM

So:
functiont test()
  function a()
  print("a")
  end
end
test.a()
or something?
Or you can't?

#6 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 11 May 2014 - 12:29 PM

no, well yes, well yes and no...

if you program correctly, then no. however using the example function declaration you have there, yes, but you don't invoke it like you think you do...

Correct programming convention (this will not allow invocation of function)
local function foo() --# note the local
  local function bar() --# note the local
    print("bar")
  end
  bar() --# you can call it here
end

bar() --# but not here

Incorrect programming convention (will allow invocation of function)
local function foo()
  function bar() --# note the lack of local, just like in your example
    print("bar")
  end
  print("foo")
  bar() --# you can call it here
end

bar() --# you can also call it here
but do you notice how we invoke it? we invoke it just like normal, meaning we may as well define it like so
local function foo()
  print("foo")
end

local function bar()
  print("bar")
end

bar()
and doing it like this reduces clutter in the global scope (which is why we should always use 'local' unless we want our functions to be accessed from the global scope)

if you give more of a description as to why you want to do this we can give you further assistance as to a method of doing what you want, or potentially steer you down a better path.

#7 Tjakka5

  • Members
  • 256 posts

Posted 11 May 2014 - 12:52 PM

You could also do it like this:

local function test(func)
  if func == "a" then a()
  elseif func == "b" then b()
  elseif func == "c" then c() end
end
local function a()
  print("a")
end
local function b()
  print("b")
end
local function c()
  print("c")
end
test("a")
test("c")
test("b")


I dont think this would be useful in anyway, but yeah, its somewhat possible.

Edited by Tjakka5, 11 May 2014 - 01:03 PM.


#8 viluon

  • Members
  • 183 posts
  • LocationCzech Republic

Posted 11 May 2014 - 12:54 PM

View PostTjakka5, on 11 May 2014 - 12:52 PM, said:

You could also do it like this:

local function test(func)
  if func == "a" then a()
  elseif func == "b" then b()
  elseif func == "c" then c()
end
local function a()
  print("a")
end
local function b()
  print("b")
end
local function c()
  print("c")
end
test('a")
test("c")
test("b")


I dont think this would be useful in anyway, but yeah, its somewhat possible.
How is this related to declaring a function in another function?
Edit:test('a") should be test("a") and it wouldn't work anyway, missing end of the if statement.

Edited by viluon, 11 May 2014 - 12:56 PM.


#9 augustas656

  • Members
  • 158 posts

Posted 11 May 2014 - 01:01 PM

I've found a slightly more helpful way using object-oriented programming, creating a table with values and functions, and I use the functions to change the values, I need this because I'm creating an API which creates a customised reader. Then you use this reader onto my read function to execute a customised read.

Thanks Anyway

#10 Tjakka5

  • Members
  • 256 posts

Posted 11 May 2014 - 01:05 PM

View Postviluon, on 11 May 2014 - 12:54 PM, said:

View PostTjakka5, on 11 May 2014 - 12:52 PM, said:

You could also do it like this:

local function test(func)
  if func == "a" then a()
  elseif func == "b" then b()
  elseif func == "c" then c()
end
local function a()
  print("a")
end
local function b()
  print("b")
end
local function c()
  print("c")
end
test('a")
test("c")
test("b")


I dont think this would be useful in anyway, but yeah, its somewhat possible.
How is this related to declaring a function in another function?
Edit:test('a") should be test("a") and it wouldn't work anyway, missing end of the if statement.

I'm sorry, it has been such a long time since I have programmed ComputerCraft stuff.
Also, the test('a") might work, but I'm not sure.

#11 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 11 May 2014 - 01:09 PM

View PostTjakka5, on 11 May 2014 - 01:05 PM, said:

Also, the test('a") might work, but I'm not sure.
no it won't. also you will get an error 'cause you've got the order of functions around the wrong way, when declaring local functions you should declare them ABOVE where you invoke them.

#12 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 11 May 2014 - 01:19 PM

From your posted code I assume you want a function to be called through indexing another function. Using metatables, specifically __call metamethod, you can make a table callable like a function:

local class = {
  test = "Hello";

  foo = function ()
    print("foo")
  end;
}

local classMT = { --// metatable of 'class' table
  __call = function (self, text) --// Define the '__call' metamethod
    print(self.test, text)
  end
}

setmetatable(class, classMT) --// Set 'classMT' to be 'class' metatable

class.foo() -->> foo

class() -->> Hello

class(" World!") -->> Hello World!

Edited by MKlegoman357, 11 May 2014 - 01:20 PM.


#13 augustas656

  • Members
  • 158 posts

Posted 11 May 2014 - 01:51 PM

I've created a function called multicompare(args) that throws an error if the amount of args is an uneven number or is below two, if not it will then run an for loop that compares all values on both sides. So like checks if a, b, c, d are equal to e, f, g, h. It can work with 2, 4, 6, 8, 10 and any amount of arguements. Comparing the first on the left with the first on the right side of the even amount of values.

I'm thinking was this wasteful, is there a way to compare multiple values like this easier? Because I've created a custom read function that allows you to customise how you want the read to end, the normal read() function will break if you press ENTER and return the finished string value. I've made it so you can select your own event, and parameters. I want to check if the event and all the parameters and equal to the event and all the parameters of a pullevent faster than a super-long if statement like this: if event == c.event and p1 == c.p1 and p2 == c.p2 and p3 == c.p3 then do something.

Regards
Augustas

#14 CometWolf

  • Members
  • 1,283 posts

Posted 11 May 2014 - 02:37 PM

Quote

the amount of args is an uneven number or is below two
Is this not the same criteria? 1 is an uneven number...

There's not really any simpler way i can think of of the top of my head, personally i think it would be easier to manage if it compared arg 1 to 2 and 3 to 4 etc. The way i handle custom events in my read function, is it's own function. Basically you pass a function as a parameter, this function is called whenever an event is received, and passed the the event and all it's parameters. If the function returns true, the read ends. This makes it far more modular, than just if event and param.

#15 augustas656

  • Members
  • 158 posts

Posted 11 May 2014 - 03:13 PM

The code is part of my API and since I don't want to give away too much of my API, I'm only giving the most relevant code, simple functions such as setPos are obviously setCursorPos, and findSize is getSize and findPos is getCursorPos etc etc.

To start off you have to create a reader, an object that has default values and you can change them by using the reader. functions. To begin with blink is setting if there's going to be a cursor blink or not, charlimit is how many characters you can write, the limit. Readlimit is how many characters are going to be displayed (not implemented yet), char is if the char is going to be hidden and if so then with what string replacing each letter. stop is the event with parameters that has to occur for the reader to terminate, as in finish reading the user's input, by default the read() function stops with pressing key ENTER (28).

For the stop function you don't have to include all the parameters required for the event, because let's say you have a "mouse_click" event and you don't care which button is going to be pressed, left mouse button, middle mouse button or right mouse button. So you can leave it out, which means it's going to be nil. The comparetables function that I use in the read accepts a paremeter called len, for length, which means how many places of both tables do I compare? So if there is going to be no button, there's going to be less parameters event, p1, p2, and no p3 because p3 defines button. The length for that being 3 because it's only event, p1 and p2.

For the char function, if you input false as the char, it will replace it with a pair of double quotes, meaning nothing will be typed at all. So you could do no blink and false which would literally mean you just input chars without seeing a blink or any sign of text. Like the most secret input.

I'm yet to implement the readlimit, although you can set it in the reader, but it won't affect the actual read function, currently I'm getting a malfunction where the cursor blink is always at the front, eventhough if you click right or left arrow keys and type it works, it's only the blink that always stays at the end and if you type extra text it will more forward, always being at the very end.

Code:
Spoiler

Regards
Augustas

#16 augustas656

  • Members
  • 158 posts

Posted 11 May 2014 - 03:24 PM

Basically if there's only 1 arugmenet or even amount, that means you are comparing like 1, 2, 3 and 4, 5 you can't do that, it's like an unfinished if statement if 1 == 4 and 2 == 5 and 3 == then. And you can't have 1 because you are comparing one with itself that's unecessary. So yeah. You understand what I maen?

#17 Inksaver

  • Members
  • 61 posts

Posted 11 May 2014 - 03:40 PM

I was trying to something similar, but ended up with a full class / object creation
This is to keep a list of coordinates:

function createCoordObject()
	--[[
	0 = go south (z increases)
	1 = go west  (x decreases)
	2 = go north (z decreases
	3 = go east  (x increases)

	compass[0] = "south"
	compass[1] = "west"
	compass[2] = "north"
	compass[3] = "east"]]--
	
	clsCoord = {} -- the table representing the class, which will double as the metatable for any instances
	clsCoord.__index = clsCoord -- failed table lookups on the instances should fallback to the class table, to get methods

	function clsCoord.new(coordName) --equivalent to VB class initialise
		local self = setmetatable({}, clsCoord)
		self.name = coordName
		self.x = 0
		self.y = 0
		self.z = 0
		self.facing = 0
		self.compass = "south"
		
		return self
	end
	function clsCoord.getX(self)
		return self.x
	end
	function clsCoord.setX(self, newVal) -- property let in VB
		self.x = newVal
	end
	function clsCoord.getY(self) -- property get in VB
		return self.y
	end
	function clsCoord.setY(self, newVal)
		self.y = newVal
	end
	function clsCoord.getZ(self)
		return self.z
	end
	function clsCoord.setZ(self, newVal)
		self.z = newVal
	end
	function clsCoord.getFacing(self)
		return self.facing
	end
	function clsCoord.setFacing(self, newVal)
		local direction = {}
		direction[0] = "south"
		direction[1] = "west"
		direction[2] = "north"
		direction[3] = "east"
		
		self.facing = newVal
		if self.facing < 0 then
			self.facing = 3
		elseif self.facing > 3 then
			self.facing = 0
		end
		-- change self.compass to match
		clsCoord.setCompass(self, direction[newVal])
	end
	function clsCoord.getCompass(self)
		return self.compass
	end
	function clsCoord.setCompass(self, newVal)
		local direction = {}
		direction["south"] = 0
		direction["west"] = 1
		direction["north"] = 2
		direction["east"] = 3
		
		self.compass = newVal
		-- set self.facing to match
		clsCoord.setFacing(self, direction[newVal])
	end
	function clsCoord.goUp(blocks)
		blocks = blocks or 1
		self.y = self.y + blocks
	end
	function clsCoord.goDown(blocks)
		blocks = blocks or 1
		self.y = self.y - blocks
	end
	--[[uses:
		location:getX()			  get current turtle x coordinate
		location:getY()			  get current turtle y coordinate
		location:getZ()			  get current turtle z coordinate
		location:setX(xCoord)	   set current turtle x coordinate eg location:setX(-235)
		location:setY(yCoord)		  set current turtle y coordinate eg location:setY(66)
		location:setZ(zCoord)		 set current turtle z coordinate eg location:setZ(125)
		location:getFacing()		returns a number 0 - 3 representing direction of player
		location:setFacing(facing)	 sets direction eg location:setFacing(1) (West)
		location:getCompass()		  returns direction as text eg "north"
		location:setCompass("X")	 sets direction using text eg location:setCompass("south")
		location:goUp(X)			increases Y coord by X
		location:goDown(X)			decreases Y coord by X
	]]--
	location = clsCoord.new("currentLocation")
	coordHome = clsCoord.new("homeLocation")
	mineEntrance = clsCoord.new("mineEntrance")
end

Three objects are created within the function, but as it has global scope, the objects can be created anywhere.
It has the advantage of changing other properties automatically, for example if you change the direction using 0,1,2,3 the text equivalent is automatically changed as well.

interestingLocation = clsCoord.new("Rocky Outcrop")
interestingLocation:setX(-243)
interestingLocation:setY(64)
interestingLocation:setZ(112)
interestingLocation:setFacing(3)
print("There is a "..interestingLocation:getName().." facing "..interestingLocation:getFacing().." ("..interestingLocation:getCompass()..")")
print("Its coordinates are x = "..interestingLocation:getX()..", y = "..interestingLocation:getY()..", z = "..interestingLocation:getZ())
> There is a Rocky Outcrop facing 3 (east)
> Its coordinates are x = -243, y = 64, z = 112
the output of interestingLocation:getCompass() is already set using the function within a function
clsCoord.setCompass(self, direction[newVal])
By the way this will not work if the shorthand version
clsCoord:setCompass(direction[newVal])
is used (colon instead of dot)

#18 CometWolf

  • Members
  • 1,283 posts

Posted 11 May 2014 - 04:00 PM

I already understood what you meant, i'd suggest you read more closely.

#19 CometWolf

  • Members
  • 1,283 posts

Posted 11 May 2014 - 04:06 PM

You appear to have forgotten that term.write moves the cursor when it writes.
  local function redraw()
  setPos(x, y)
  term.write(string.rep(" ", w - x + 1))
  setPos(x, y) drawstr()
  --move the cursor back to where it's supposed to be here
  end


#20 augustas656

  • Members
  • 158 posts

Posted 11 May 2014 - 04:14 PM

Updated Version:
Spoiler

Unlike the read() function, this for some reason doesn't move the entire string when there are characters out of bounds, so if I keep typing characters after the string has reached the end of the screen, it will go beyond the border and I will not see. How can I fix this!? So frustrating can't find the error, looked through my code and it's literally identical apart from the additions to the bios.lua one.

Edit: I highlited red where I think this problem occurs.

Edited by augustas656, 11 May 2014 - 04:48 PM.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users