Wednesday, April 10, 2013

Unity3D Serialization


Another infrequent post, another entirely different programming topic.

I'm developing a mobile game with Unity3D (C# only), and I rolled my own serialization and deserialization code for it. I recently decided to see what stable general solutions exist, and found these:


Sunday, February 5, 2012

Bazaar Explorer, Launchpad, Qt: Configuration Issues

Two friends and I started Chaos2D yesterday. We ended up deciding to use QtCreator as the IDE and Launchpad (Bazaar) to manage the project. We downloaded Bazaar Explorer, naturally, and the fun began. This post is a guide for my past self; I'm sending it back next time the DeLorean passes by. Note that my experiences are from Ubuntu 11.10, but of course you have that by now.

Firstly, in QtCreator select Tools > Options > Version Control > Bazaar. Enter /usr/bin/bzr in the Command field, and also fill in your Launchpad username and password (I'm not certain those are required). I guess QtCreator doesn't provide for getting the source, but once you have a Bazaar repository it can take it from there.

While typing this, I couldn't remember a detail and had to get some help (important!) from Google. I think I also had to make an OpenPGP key to get Launchpad to acquiesce to my request.

Then Bazaar complained about not being able to authenticate Launchpad; I couldn't find anything on Google about that, so I just said yes and it added Launchpad as a trusted site. At this point I decided to sign the Ubuntu Code of Conduct since I had the OpenPGP key anyway.

Finally, I didn't like retyping my SSH password every time. This is apparently the proper, secure solution. I didn't know about it at the time, so I did this and changed my Launchpad password to something I don't use promiscuously.

Oh, I almost forgot. Bazaar Explorer seems to ignore all ignore rules, so I recommend directly using the less-bold bzr command. I might have said that anyway, after this bizarre experience.

Sunday, May 2, 2010

Learning Lisp

This journal was originally posted to Google Wave on February 7, 2010 and edited incrementally. The resulting discussions are not yet included.

I've heard a lot about Lisp, especially now that I'm in an AI Programming course in college (but it's mainly regarded as a relic in there). I love JavaScript's functional features, but I hadn't managed to dive into their source until now. I'm using Common Lisp for now, with some elisp along the way, although Scheme probably won't be far behind. So this is going to start out as a journal of my experiences.

Background: I know about eight programming languages already, and feel that I can learn any I like. My favorites so far are JavaScript and then Python, precisely because of the Lispy features, so I think I'll love Lisp once I'm fluent in it. On the other hand, I have only programmed as a hobby so far. Keep that in mind if you try Lisp out yourself; your mileage may vary.

I installed clisp+slime using this guide: http://www.osix.net/modules/article/?id=912

I'm using this tutorial: http://www.gigamonkeys.com/book/

2/7/10

I can think of two gotchas I've run into so far: a function body doesn't get wrapped in parentheses, and the first parenthesis goes before the called function's name, not after. Oh, and lists aren't supposed to be comma-delimited.

Naturally, macros are kind of hard to grasp. But I finally decided the most concise description is lazily-evaluated functions, based on the tutorial's explanation.

Right now I'm wondering how to do classes (prototypes?!), although I saw define-class and define-method mentioned in library code. But I'll wait until the tutorial gets to those.

2/8/10


For my inaugural Lisp project I'm implementing the JavaScript object model into Common Lisp. I'm learning a lot about CL's Lisp-2 nature and thinking I'll like Scheme more. But I won't decide that until I've mastered the essential features of CL such as macros and CLOS. (Note to self: Those ugly punctuation doo-hickies are called "read macros.")

But I really need to learn how to debug in emacs+slime+clisp. For that matter I need to learn to use the REPL for programming.

2/11/10

Because Common Lisp is a Lisp-2, that is a Lisp with two namespaces for variables and functions:

  • (fdefinition `foo) is the best place to SETF a global/dynamic function, if the global function FOO is already defined. I hack this up by saying (defun foo () ) before I need to SETF it.

  • If a function is instead assigned as a variable it must be called with (funcall foo arg0 arg1 ...) or (apply foo args).

  • To bind a function in the local/lexical scope and not need to call it with FUNCALL/APPLY you must alias it:
    (let ((foo (lambda ()
    #| ... |#)))
    (flet ((foo (&rest args)
    (apply foo args)))
    ;Now we can call it without FUNCALL:
    (foo)))

  • Note that the above code demonstrates what "Lisp-2" means: The function FOO is in a different namespace than the variable FOO, and their values are not inherently related. The function FOO can be get'ed with #'foo.


Why?

The Common Lisp community explains that the power of CL macros justifies the Lisp-2 nature. I am not yet qualified to give an opinion on the matter.

2/13/10

The LOOP macro had me stuck for a long while (no pun intended) on a syntax error. I finally got that cleared up, but now I have an infinite loop - bah. Anyway, here are the two things I learned, using http://www.ai.sri.com/pkarp/loop.html as my primary reference... (The chapter in Practical Common Lisp helped too, but only by mentioning the word "do" - I got too excited to keep reading.)

  • Sentry variables for a 'while' loop must be assigned outside the loop itself, in a LET for example. ("for x from y" might work too; I didn't check. But "for x = y" makes that assignment every iteration.)

  • The 'do' after the condition-form of your 'while' is there for a reason. This is what kept me stumped for a few days, because the error just said "syntax error" instead of "'do' expected." I decided to put the 'do' on the same line as the 'while' since I don't see any reason they might ever be separated.


2/16/10

In JavaScript, this is a pseudo-variable that changes for each function but cannot be assigned to. I wanted to make my JS functions syntactically similar to native Lisp functions, so I declared the function's lambda list and body as parameters to the function that manufactures JS functions (the Function constructor).

I managed to add this to the list of arguments passed from outside, and declared it in the lambda list. But then I needed to declare a new function using a (list "variable" "like" "this" "one") as the lambda list and the passed-in body. That didn't work; apparently the lazy compiler insists on knowing what each function looks like at compile-time. </self-deprecating-sarcasm>

Alright, enough about JS mechanics; here's the solution I got on a forum:

(defvar *this* "JavaScript details")
(defun makefun (name lambda)
(labels ((havefun (&rest args)
(let ((*this* "more details"))
(apply lambda args))))
#'havefun))
(funcall (makefun "will travel" (lambda ()
(print *this*))))


I didn't compile that, but it should print "more details." What's sad is that I had read about special variables shortly before asking that question (a day at most, I think). I understood them, but for some reason the long way around the tree occurred to me first, as always.

One good thing about this way (other than that it works, isn't a hack, and looks cleaner) is that JavaScript's other variable that mysteriously shows up in every function with a different value - arguments - doesn't require that so many (two) pieces of code be changed in order to accommodate it.

Saturday, January 9, 2010

Where is Google's nemesis?

I love Google's products. The other day I learned that Chrome had been released for Linux, and then that led me to also discover Wave (granted, it's federated and open-source). I started a project for an extension to Wave on Google Chrome. Then I had to get help building it at Google Groups, which will notify me of replies via Gmail. Now I'm posting about all this on Google's blog service.

I know there are non-Google alternatives for some of these. I formerly used Firefox, but now I'm getting attached to Chrome - although WebKit and the lack of Java sometimes get annoying. I tried JavaForge for project hosting but was disappointed. I use non-Google forums frequently (when I'm into forums, anyway). I have email accounts with Opera, Microsoft, and maybe some other sites, but they don't work as well. I have a Wordpress blog for general topics. You might call me a Google fan-boy, but out of what they do they do much of it best.

Google was founded by some young entrepreneurs who challenged the big players. The company still has that youthful, small-company air, but now it is the big player. Some people say Google is becoming Microsoft; I think Google is just doing well. But having only one or a few big kids on the block is a bad thing. Who's going to be the upstart that keeps Google on its toes? Is anyone concerned enough to do that right now, or does that youthful air reassure most of us that the big G is harmless? Is there enough creative talent not employed by Google to challenge it? Should we expect the nemesis to emerge from Google itself when things get bad enough? In the meantime, how should we regard Google products? And for all of your answers to the above: Why?

Sunday, July 12, 2009

Best practices?: Modifying HTMLCollections in IE

I just ran into a very weird IE quirk, and I'm wondering what the best practice would be regarding it. (I've only tested in IE7; it might show up in other versions.)

Before I had IE installed, I had to modify a form and then find my elements in it to modify them again, and the elements' names were the most convenient way to accomplish the second part. So of course I went for the form.elements collection, and this works fine in Firefox. But not only is this property actually the form itself in IE, the developers apparently didn't read this part of the spec:
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-1019015399
Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
To demonstrate what this means, I threw together a small test page (post continues below):
<html>
<head>
<title>IE DOM modifications</title>
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
<script type="text/javascript">
window.onload = function(){
var form = document.forms.namedItem('test');
var input = document.createElement('input');
input.name = 'foo';
input.type = 'hidden';
input.value = 'bar';
form.appendChild(input);
console.log(form.childNodes[0]);
// form[input.name] = input;
console.log(form['foo']);
console.log(form.elements.namedItem('foo'));
};
</script>
</head>
<body>
<form name="test">

</form>
</body>
</html>

If form[input.name] = input; (a very ugly hack) is commented, the first call to console.log works but the other two don't. Otherwise, the first two work but the last still doesn't.

So here's my question: Is this the best way to workaround this quirk? The idea of form elements being direct properties of the form isn't in the standard, and the standard namedItem function remains broken. I managed to still use namedItem by default, but I really don't like the hack at all.

Here's how I retrieved my element:form.elements.namedItem(name) || form[name]

Friday, June 5, 2009

Pandora stopped working, Firefox's fault?

Pandora suddenly stopped in the middle of a song today. I was afraid it wouldn't ever work again, which would seem to herald the old problems returning and a new laptop purchase. I refreshed the window, same problem. Then I closed Firefox (had to end it in System Monitor) and Pandora was revived. Yay!

Saturday, May 30, 2009

My Ubuntu Adventure

A long time ago, I encountered the open-source movement as a hobbyist programmer (which I still am, unfortunately) and wanted to try Linux out. I found the Debian site, but the instructions were way over my head so I didn't dare touch it. I'm not sure whether I had my laptop at that time, but I was at least expecting to buy one. Some time later, I met a guy named Nathan and we became fast friends. While he had never used Linux, he knew of Ubuntu and suggested that I request a CD. I did, and what a learning experience it's been!

I was completely ignorant of partitions, and I think I resized the one on which Windows XP Professional was pre-installed. Hey, where'd my data go? Over the next year, I had loads of newbie problems and started experiencing really weird bugs:

  • Certain keys would stop working for no apparent reason;[1]

  • Firefox started giving JavaScript errors about ordinary whitespace;[2]

  • Flash would crash Firefox;[3]

  • sound of different types progressively failed until I had almost none left;[4]

  • I tried to fix Apache by reinstalling and apt-get choked - hard;[5]

  • programs compiled from the same source by gcc became inconsistent;[6]

  • diffs contained corrupted data.[7]

So now, even though I was fighting to keep coding, I had run into crippling problems with JavaScript, PHP, and C. Even fixing really basic bugs in GNOME which didn't require testing, I was encumbered by diff's corruption. So now I was reduced to typing (also encumbered) and playing games until I could reinstall.

After I finally got my /home directory backed up correctly, I used fdisk to repartition because I had been warned of the Live CD's "idiosyncrasies" (although I did have to tweak from the CD because of cylinder boundaries). I installed Jaunty and put the data back where it belonged. That messed GNOME up and broke the sudo command[8], both presumably because the data was generated on Intrepid. So for a while I only ran on the Live CD, which uses RAM as hard drive space; that got old really fast, although Google's storage came in handy.

I tried to install Jaunty on another partition, but the Live CD's second option installed it on a very small one that I had intended for something else. I only found out when the JRE required more space than I had. I had to repartition because the second installation made new sections that I didn't want. After figuring out how to work around memory conversion bugs in the Live CD's partition editor, I finally got a clean install.

I installed Jaunty again to get a programming partition, and again on the partition I intend for Windows so I can debug my /home data. All three use the same /home partition so I can easily transfer data. My backup has a profile folder named "chris" as does my main install, so I had to extract without ruining the clean profile. I managed that by renaming the real one "_chris" and copying the extracted data to the temporary installation's profile. The user ids were (I guess) the same for both users, so ownership was automatically transferred.

The other time that I extracted my data, I only ran into problems after restarting. This time, I tried running Pandora, to lighten up my debugging tedium, and it froze Firefox like the bad old days. So now I know two things about the remaining bugs:

  1. They reside in my profile;

  2. they are not all triggered at startup.

This post is intended for two purposes. I would really like to get some help in the comments, as the gurus on Ubuntu Forums seem tired of my queries. I also hope to help the poor Googler who finds my experience all too familiar, and maybe even get whatever bug(s) are behind it fixed.


  1. http://ubuntuforums.org/showthread.php?t=1012239

  2. http://forums.mozillazine.org/viewtopic.php?f=25&t=940905

  3. I didn't make a thread for this case, although this one is related; the above case was later and (I think) cross-browser.

  4. No thread for this one either, but this is related.

  5. http://ubuntuforums.org/showthread.php?t=1038787

  6. http://cboard.cprogramming.com/c-programming/114634-exiting-gtkplus-allowing-cli-continue.html

  7. http://ubuntuforums.org/showthread.php?t=1126698