Jump to content


Hawk777's Content

There have been 34 items by Hawk777 (Search limited from 10-February 22)


By content type

See this member's


Sort by                Order  

#145362 Extended ASCII / New Font

Posted by Hawk777 on 17 September 2013 - 12:40 PM in Suggestions

View Postimmibis, on 15 September 2013 - 06:07 PM, said:

Doesn't LuaJ mess up characters over 127?

At least when sending over modems, yes. Also, according to various people, at Certain Other Unspecified Times. This is obviously a hindrance to UTF-8 or extended ASCII, but might be solvable (particularly as, according to chatter on the IRC channel, LuaJ may be going away at some point).



#145360 [CC1.53][MC1.5.2] MiscPeripherals 3.3

Posted by Hawk777 on 17 September 2013 - 12:32 PM in Peripherals and Turtle Upgrades

View PostHawk777, on 21 August 2013 - 01:57 AM, said:

Hello! I see in the changelog for version 3.1, “Fixed Electronic Signal Controllers losing data on reload”. Unfortunately, this doesn’t seem to work. I’m running v3.1 (part of FTB-Lite), and someone I talked to about this bug tested it in v3.3 and it was still there: after shutting down and restarting a world, the link from the ESC to a distant signal (even if the two objects were in the same chunk) was broken and had to be retuned before the ESC would again send an aspect to the signal.

This still happens in 3.4b2.



#145060 Extended ASCII / New Font

Posted by Hawk777 on 15 September 2013 - 02:29 PM in Suggestions

Well, personally I would prefer CC to get proper Unicode support (even if only on the terminal, even if strings are still considered byte sequences rather than character sequences, since that’s a core Lua thing). Then we could have all the accents we want, and the line- and box-drawing characters.



#144073 A Smaller Top Level Coroutine Override

Posted by Hawk777 on 09 September 2013 - 01:28 AM in Programs

View PostElvishJerricco, on 09 September 2013 - 01:25 AM, said:

According to the homepage (http://luaj.org/luaj.html), it is in fact an interpreter. It doesn't look like LuaJ is Lua→JVM Bytecode.

Except for this sentence on that very page:

Quote

In this model the lua bytecode can be compiled directly into Java bytecode, lua source can be turned into Java source, lua bytecode can be interpreted, or all techniques can be mixed and matched depending the needs of the host runtime.

I guess it provides multiple options, but I think ComputerCraft uses JITing (and certainly the sentence “Version 2.0 is a significant rewrite whose implementation leverages the Java stack instead of a separate lua stack” explains why Java threads have to be used to implement coroutines).



#144071 A Smaller Top Level Coroutine Override

Posted by Hawk777 on 09 September 2013 - 01:17 AM in Programs

View PostElvishJerricco, on 09 September 2013 - 01:07 AM, said:

If I'm not mistaken, the JVM is the fastest virtual machine out there except for maybe LuaJIT2 (for those that don't know, this is not Lua nor LuaJ). Both of them achieve near-C speeds, so I'm surprised they didn't feel comfortable doing an interpreter.

EDIT: Just realized that if we were using LuaJIT, we could write a Lua interpreter in Lua with decent performance... Meh.

Well, I don’t know. The JVM is pretty decent, so I think it makes perfect sense for LuaJ to generate JVM bytecode as output—if it’s even somewhat sensible, it means the Lua code gets to run really fast by taking advantage of all the JVM’s optimizations.



#144069 A Smaller Top Level Coroutine Override

Posted by Hawk777 on 09 September 2013 - 01:03 AM in Programs

View PostElvishJerricco, on 09 September 2013 - 12:44 AM, said:

I'm sorry. I was going off of my knowledge of Lua, and expecting LuaJ to be a straight port of Lua. It appears LuaJ does in fact do it differently. In my opinion, it is a mistake of LuaJ's to do coroutines in such a way and it could have been easily avoided by sticking closely to the C code.

I agree, it’s a bit odd. The reason LuaJ does this is that, if I’m not mistaken, LuaJ isn’t a pure interpreter; rather, it translates Lua code into JVM bytecode in dynamically generated classes and then runs it natively in the JVM. This has the problem that Lua’s execution state is now implemented as a Java execution state, and the lightest-weight thing Java provides that can encapsulate an execution state is a thread—Java doesn’t have coroutines, therefore LuaJ can’t implement coroutines as cheaply as you would expect while still translating to Java bytecode.



#144060 A Smaller Top Level Coroutine Override

Posted by Hawk777 on 08 September 2013 - 10:55 PM in Programs

View PostElvishJerricco, on 08 September 2013 - 12:52 PM, said:

View PostHawk777, on 08 September 2013 - 12:47 PM, said:

Why is this useful? How about because it cuts the number of (real-world) Java Minecraft threads in half or more, because every coroutine uses a thread? A decent OS will make sleeping threads not take up many resources, but eventually there is a limit after which you won’t be able to run any more computers.

This is wrong. Coroutines aren't real threads. The LuaJ VM is just allowed to choose what Lua code is running at what time. If coroutines were multithreaded, we could run two of the simultaneously.

Sorry, but it’s actually not wrong. Each LuaJ coroutine is implemented as a native Java thread. The reason why two of them can’t run simultaneously is simply because they’re written to block until that particular coroutine is supposed to run. If you don’t believe me, run Minecraft, create a bunch of coroutines, and then go check out how many system threads your Java process has (in Linux this is very easy to do, just check how many subdirectories there are in /proc/`pidof java`/task).



#144002 A Smaller Top Level Coroutine Override

Posted by Hawk777 on 08 September 2013 - 12:47 PM in Programs

Why is this useful? How about because it cuts the number of (real-world) Java Minecraft threads in half or more, because every coroutine uses a thread? A decent OS will make sleeping threads not take up many resources, but eventually there is a limit after which you won’t be able to run any more computers.



#141696 recognize server restarts

Posted by Hawk777 on 25 August 2013 - 02:15 PM in Ask a Pro

View PostBubba, on 25 August 2013 - 12:02 PM, said:

View PostHawk777, on 25 August 2013 - 11:38 AM, said:

It might be the case that the original contents of the file are still there. It might be the case that the file is empty, because it was truncated when opening in write mode but you never even got to the write(x). It might be empty because the open truncated it, the code did get to write(x) and write(y), but the shutdown happened before you got to the flush. Or, alternatively, maybe it only has x in it but not y, because the system decided to flush buffers after the write of x (maybe x was fairly large). In all these cases, you see data loss, and flush is not sufficient to safely replace a file.

What do you think append mode is for? You will experience no data loss if you open the file in append mode. Other than the new data that you're trying to write. This of course would be sad, but it is not something that opening a new file and writing would be able to fix anyway.

Well, if you wanted to keep the original data as well as the new data, then sure, use append mode, and none of this matters. Normally one doesn’t though. Most of the time you have some data (maybe a serialized table), and once in a while you decide to update it, and you want to replace the old data with the new data.

Quote

Quote

The only safe solution is to write the new data to a different file and be sure it’s fully on-disk before deleting the old file—flush is part of that, but not all of it.

This takes more time than a simple flush does (though I'm sure that either way the difference is negligible). What I'm saying is not that you're wrong, per se, it's just that you are not using the most efficient method. Overall, flush is the fastest, easiest, and most reasonable way to save the new data. A flush after each write will ensure that the data is saved, and it has the added bonus of not needing a temporary file.

1) New file? Open in write mode. You have nothing to lose.
2) Adding data? Open in append mode. You will not lose the original content.
3) Modifying old data (as in completely overwriting, not adding) is the only case I can think of where you would want to use temporary files.

Oh and you seem to assume that a crash will occur at the same exact moment as writing to a file. What are the chances of that? Quite low. Flush will save the file in the event that a crash occurs at a later instance, but you still want to use the same file handle, which is I think all that the OP is asking.

Of course, for a new file or appending data, you don’t need to do this. For replacing the contents of a file, you do. Also, of course the chance of the server going down at the exact moment you’re writing new data but haven’t finished yet is pretty low, but then, good software engineering practice should be about building software that works, not just software that works most of the time.



#141671 recognize server restarts

Posted by Hawk777 on 25 August 2013 - 11:38 AM in Ask a Pro

View PostBubba, on 25 August 2013 - 06:58 AM, said:

Or just use file.flush(), which saves the file and allows you to continue using it...
See here (Not CC Lua, but it still applies): http://www.lua.org/pil/21.3.html

Not safely, you can’t. What if I do write(x); write(y); flush()? What if the server goes down after write(x) but before write(y)? It might be the case that the original contents of the file are still there. It might be the case that the file is empty, because it was truncated when opening in write mode but you never even got to the write(x). It might be empty because the open truncated it, the code did get to write(x) and write(y), but the shutdown happened before you got to the flush. Or, alternatively, maybe it only has x in it but not y, because the system decided to flush buffers after the write of x (maybe x was fairly large). In all these cases, you see data loss, and flush is not sufficient to safely replace a file. The only safe solution is to write the new data to a different file and be sure it’s fully on-disk before deleting the old file—flush is part of that, but not all of it.



#141618 recognize server restarts

Posted by Hawk777 on 25 August 2013 - 01:57 AM in Ask a Pro

The usual way to safely replace a file in real-world programming is to create a new file with a temporary name, write the data into it, and then rename it on top of the original file. That way, you’re guaranteed that no matter where your program stops running (e.g. crashes), either the old file exists intact or else the new file is fully written—there is no case where you lose the file completely (if you add an fsync call, this is even safe across power failures). I suspect doing something similar in ComputerCraft—writing a temporary file and fs.move-ing it on top of the original—is probably about the best way to be safe while writing files.



#141020 [CC1.53][MC1.5.2] MiscPeripherals 3.3

Posted by Hawk777 on 21 August 2013 - 01:57 AM in Peripherals and Turtle Upgrades

Hello! I see in the changelog for version 3.1, “Fixed Electronic Signal Controllers losing data on reload”. Unfortunately, this doesn’t seem to work. I’m running v3.1 (part of FTB-Lite), and someone I talked to about this bug tested it in v3.3 and it was still there: after shutting down and restarting a world, the link from the ESC to a distant signal (even if the two objects were in the same chunk) was broken and had to be retuned before the ESC would again send an aspect to the signal.



#126863 CC Table Limit *Rips hair out*

Posted by Hawk777 on 17 June 2013 - 12:25 AM in Ask a Pro

Counterargument, https://en.wikipedia...rative_solution. More generally, I fully agree that recursion is often easier to understand for certain types of problems, but I stand by my claim that it is never strictly necessary. If you don’t believe me, consider the fact that you can write an interpreter for a programming language, or even a CPU emulator, without using recursion, and then, having done so, can run recursive programs inside it.



#126750 Watchlist e-mail notification

Posted by Hawk777 on 16 June 2013 - 01:53 PM in Wiki Discussion

Lochie, that looks good, but I’m not sure about the syntax. Does the subscribe command take two parameters, the first being the event type and the second being a page name to watch, or how does it work?



#126746 CC Table Limit *Rips hair out*

Posted by Hawk777 on 16 June 2013 - 01:30 PM in Ask a Pro

Recursion is never necessary. You can always replace a recursive function with an iterative function and a stack implemented in general purpose storage, e.g. a table, storing what you would otherwise store in local variables and the program counter in the recursive function. The result may or may not look very nice, but it’s possible 100% of the time.



#123158 [Question] Is there is anyway to provide such functionality?

Posted by Hawk777 on 02 June 2013 - 11:45 PM in Ask a Pro

HTTP API to talk to a Web server is one possible solution to communicating with the outside world. Another, which I invented before ComputerCraft had an HTTP API, is that you have the CC computer write to a file on its hard drive and then you have a dæmon running that watches for files being created and modified using inotify.



#121891 Watchlist e-mail notification

Posted by Hawk777 on 29 May 2013 - 11:03 PM in Wiki Discussion

I could do that, though CCWiki shows all recent changes rather than only changes to pages on my watchlist. Also I don’t know if it shows changes to talk pages?



#121640 Watchlist e-mail notification

Posted by Hawk777 on 28 May 2013 - 11:58 PM in Wiki Discussion

Wikipedia and the IndustrialCraft wiki both have “Email me when a page or file on my watchlist is changed” options (or similar wording) at the bottom of the “User Profile” tab of the preferences area. CCWiki does not. Any chance it could be turned on? Polling CCWiki just to check if any watched pages have changed is annoying!



#121384 Mobile Version

Posted by Hawk777 on 28 May 2013 - 03:28 AM in Wiki Discussion

Wikipedia has a mobile version, and the Wikimedia Foundation tends to be pretty in favour of open source software, so I would be surprised if you couldn’t find that code (and, of course, it would share its database with the desktop view of the same wiki, which would be what we want here as well). Whether the code is packaged up in a useful shape for deployment to another site or whether it’s a pile of hacky patches, well, that’s a different matter…



#121382 [Question] Thread-safe Sleep function

Posted by Hawk777 on 28 May 2013 - 03:22 AM in Ask a Pro

View PostLyqyd, on 26 May 2013 - 09:40 PM, said:

You will not encounter any problems if you use coroutines in the usual manner (the event-based model). That section of the coroutines page is highly misleading in its wording.

As the author of that section, I respectfully object to it being described as “highly misleading”. If you look at introductions to coroutines in general on the Internet, you generally end up reading about something like a lockstep producer-consumer pair. If you built something like that (a supposedly typical example of what coroutines would be used for) using Lua coroutines in ComputerCraft and then called a blocking API function from one of those coroutines, it would explode spectacularly. Yes, there are cases where you can use the blocking routines from inside raw coroutines safely, but those cases are very limited—namely, only if your coroutines happen to be dispatched by events from the system event queue, which is just one possible case out of many. Also, I do mention at the bottom of that section that one option is to “arrange to handle event dispatch the same way that the parallel API does so that the blocking functions work properly”.

Perhaps any further discussion of this should be taken to the talk page on the wiki, if you feel there is something that should be changed? I see you added a NeedsWork template, but didn’t actually explain what the problem was.



#121380 call function from string

Posted by Hawk777 on 28 May 2013 - 03:08 AM in Ask a Pro

If you really, really want to access a function defined in the current file by name with no special syntax used at point of definition, what about this?

function myfunc()
  print("Hello World")
end

fname = "myfunc"

getfenv()[fname]()

The above snippet outputs the string “Hello World”.



#116880 Is MediaWiki too hard to use?

Posted by Hawk777 on 10 May 2013 - 04:00 PM in Wiki Discussion

The IntegratedRedstone wiki for Redpower was on Wikispaces, which has a WYSIWYG editor. Editing was HORRIBLE. Then Danol started a MediaWiki-based wiki for Redpower, which is now the only thing I edit because it’s not painful.



#116878 Question about Newlines

Posted by Hawk777 on 10 May 2013 - 03:50 PM in Ask a Pro

View Posttheoriginalbit, on 07 May 2013 - 08:28 PM, said:

View PostHawk777, on 07 May 2013 - 06:32 PM, said:

I’m not sure what problem you’re having, but you can certainly get an HTTP response and see newlines in it. If you do an HTTP get and then call readAll() on the returned handle, you get a single string which contains newlines in the form of character number 10.
What the........... how does this............ i dont even............. it doesn't answer OP question, it would just print ? in place of all the newlines... (btw the newline byte is 10)

That would be because I didn’t understand the question properly then. I thought the question was about how to find the newlines in an HTTP response, not about how to move the cursor on the screen!



#116144 Question about Newlines

Posted by Hawk777 on 07 May 2013 - 06:32 PM in Ask a Pro

I’m not sure what problem you’re having, but you can certainly get an HTTP response and see newlines in it. If you do an HTTP get and then call readAll() on the returned handle, you get a single string which contains newlines in the form of character number 10.



#116142 Advanced Lua Topics - Coroutines

Posted by Hawk777 on 07 May 2013 - 06:23 PM in Tutorials

You missed a couple of return values from status: running (if it is the currently running coroutine) and normal (if it is an ancestor, or superior as you call it, of the current coroutine).