Archive for May, 2008

Haxe + Papervision = Hot damn!

Update

——-

Do the math! I encourage you! Check my figures! Could it really be true?

A google search on haxe+papervision lead me to a mailing list link to HaXe版PaperVision3d, which made me think: yeah! (pronounced “yehah”, not “yee-ay”).

As they say in Finland: let’s get it on!

 % haxe pv3d.hxml 2>&1 | tee e
 org/papervision3d/objects/DisplayObject3D.hx:951: characters 14-18 : In Flash9, null can't be used as basic type Float

Oh, snappity-snapperoo! Wuh happen’d?!

I’m totally gunna use the source, Ben! Thx! You ℛ☉✖✘☮ℜ⚡!

 % vim $( grep -w characters e | cut -f1,2 -d: | sed 's,:, +,' )
 #### this is inside vim:
     private function getScale():Float
    {
        if( this._scaleX == this._scaleY && this._scaleX == this._scaleZ )
            if( Papervision3D.usePERCENT ) return this._scaleX * 100.0;
            else return this._scaleX;
        else return null;   // <--- this is the line
    }

So it’s kvetching about null for Float… whatever… I’ll just change it to be “0″… Changed that in 4-5 places and now the coolio-demo is happy: pv3d_haxe.swf

For some reason, that link is fark-tarded, from googoo, but if you download it and hit if from local it looks kinda like this, but spins like a dervish!

Sweet! This is going to be fun!

———————
IE must be destroyed.

Comments (6)

Have Browser – Will Travel

These days I’m mostly a Java guy, but for a number of years now, I’ve been convinced the future of development is the browser.

Yup, I put my money on Javascript.

But… I also put a little bit of cash down on SWF. Once I found I could develop for it under Linux thanks to mtasc and later Haxe.

IMO, here are the rules:

  1. you have to be able to develop for it under Linux
  2. it has to run in the browser
  3. it has to be completely free (as in beer, as in cash)

Some people won’t like these rules and will want to write in ActiveX or some other proprietary crap, sorry, you can’t exclude developers. Every developer you turn away (Qualcomm, I am talking about your crappy BREW), is going to try and destroy you. Oh, maybe not directly, but we will seek out a platform where we can produce software, and that platform will kick their platform right square in the sitting down parts.

Other people will say that you will alway have to have a server for your clients. P2P shows that is just wrong. It was a better network model back in the day, until scaling squashed it and now bittorrent shows how it will scale. The right answer to where you persist your data is everywhere.

What about mobile devices? They will run HTML 5.0 browsers. They may also run flash. I don’t know why they won’t run Java. I really don’t. “My applet? Why hast thou forsaken me?”

What about OpenGL and DirectX? Too easy: canvas.getContext(“3d”);

But IE doesn’t support the canvas element you say! That is why IE must be destroyed. Safari, I’m putting you on notice. I don’t like hearing you not supporting Firefox API’s.

Cross-browser scripting needs to end now.

Today.

Refuse to support anything but Firefox.

Don’t think

  1. it is an accident you can’t write BREW applications for you Verizon phone
  2. Microsoft isn’t the reason the canvas tag isn’t used everywhere
  3. Apple doesn’t want to be Microsoft
  4. IBM loves Linux

Do think:

  1. major technology companies are doing everything they can to keep developers in check
  2. we will overcome
  3. OSS all the time
  4. you sell software, not code

Javascript or Haxe? The good news is we don’t really have to choose.

:-D

---------------------
IE must be destroyed.

Comments (1)

Scripting with ANSI Color Codes

Oh the console! Love it or loath it, if you engage in computer actions you probably end up spending a lot of time looking at a console.

Of course not all consoles are created equal. Some consoles are really just the equivalent of

while line=nextLine() ; do print line ; end

Typically this is reserved to crappy IDE’s (yes, I know that’s redundant, I’m making a hah-hah).

Some deluded souls think cygwin is a real console, only to discover half-way into trying to actually get something done that it ends up going nutso and spewing text in the most unlikely of locations. Infrequently this can lead to a series of awkward questions in the ER.

Gnome’s terminal is pretty adequate, and of course you can’t go wrong with xterm or a host of other well written, robust terminals that oddly enuff seem to show up only under flavors of UNIX (yes, netBSD… err.. Mac counts too).

Why is writing a solid console implementation so difficult?

Because a console is not about printing lines of text. A terminal is more like a pixel-based display where ever pixel is a character + presentation information.

It is a highly sophisticated user interface. Unlike the farktarded point-and-click UI’s popular today for no good reason which use a maximum of say 8 buttons, a console typically has 108+ buttons.

Hah-hah, indeed. More importantly a console is really an interpreter.

No, I don’t mean the shell, I mean the console is an interpreter. Just like with shells we have bash, tcsh and crapsh, terminals come in flavors like VT100, VT110, VT220, 3270, 5270 and plethora of others.

Since a terminals has to accept all sorts of input, the language for controlling the terminal is a done via “control codes.” Typically a control code is just a string which is difficult to type.

For example: echo <ESC>[33mCheese<ESC>[0m

What is that <ESC>? Typically it is character 27. How do you type it? On a lot of consoles, you type it like this:

  1. hold down the control key
  2. press the 'v' key
  3. let go of the control and 'v' key
  4. press the escape key

Pretty neat, huh? That works for ANSI/VT100-based terminals. Not for all terminals. Luckily for us, that's just about all we really care about.

Of course a real console application (eg: vim) cares about all terminals and you start to move away from writing control codes directly and towards using terminal apis like curses/ncurses PDQ.

For hacking purposes, VT100 terminal codes will do just fine.

I know.. what a load of historic irrelevant blather and so what and quit wasting my time! What is it good for?!

When was the last time you looked at a log file? Let me put it a different way, when did you stop looking at log files? Chances are you are watching a log file right now! I know I am!

What percentage of log output do you care about for a given task? 10%? 2%? Isn't it a drag that it just blends in with the rest?

Of course you could grep it out, but then you lose the context... Or you might forget a term and have to reproduce the problem again (again [again]).

IMHO, a kick-aspirin use for VT100 color codes is for log highlighting, and it is some simple, it can be easily scripting into a general use script.

Here is the kind of usage I would like:

usage: cat foo | line_lite.sh ( pattern highlighting )+

pattern         is a ala grep
highlighting    is a colon separated list of colors

the colors are 

    reset        bright      dim         underline    blink
    reverse      hidden      black       red          green
    yellow       blue        magenta     cyan         white
    black_bg     red_bg      green_bg    yellow_bg    blue_bg
    magenta_bg   cyan_bg     white_bg

That way I can use it like: tail -f some.log | line_lite.sh Exception red “some other text” green:underline

In order to make this happen, I need to convert that red, green:underline crap to the appropriate VT100 code.

Natually, I do this with sed:

_line_lite_color_to_code() {
    echo ${*} | sed "s,reset,0,g;s,bright,1,g;s,dim,2,g;s,underline,4,g;s,blink,5,g;s,reverse,7,g;s,hidden,8,g;s,black,30,g;s,red,31,g;s,green,32,g;s,yellow,33,g;s,blue,34,g;s,magenta,35,g;s,cyan,36,g;s,white,37,g;s,black_bg,40,g;s,red_bg,41,g;s,green_bg,42,g;s,yellow_bg,43,g;s,blue_bg,44,g;s,magenta_bg,45,g;s,cyan_bg,46,g;s,white_bg,47,g;s,:,;,g"
}

_line_lite_code() {
    _line_lite_color_to_code ${*} | sed 's,.*,ESC[&m,'
}

This will convert "green:underline" to [32;4m

Now we just need some way to do our matching and add the color code. Once again, it's sed time.

For each pair of pattern/color, we create a sed expression like: s!.*.*!&!g;

In this case we'd have s!.*some other text.*![32;4m&[0m!g;

All that we have to do is concatenate our sed expressions for each pattern/color pair and then call sed.

Viola! Arbitrarily colored logs!

Here is sample output from something that's not a log:

% jar_minder_javap sun.security.provider.PolicyFile | line_lite.sh 'static'  red:bright
Compiled from "PolicyFile.java"
public class sun.security.provider.PolicyFile extends java.security.Policy{
    public sun.security.provider.PolicyFile();
    public sun.security.provider.PolicyFile(boolean);
    public void refresh();
    public boolean implies(java.security.ProtectionDomain, java.security.Permission);
    public java.security.PermissionCollection getPermissions(java.security.ProtectionDomain);
    public java.security.PermissionCollection getPermissions(java.security.CodeSource);
    protected java.security.cert.Certificate[] getSignerCertificates(java.security.CodeSource);
    static boolean access$002(sun.security.provider.PolicyFile, boolean);
    static boolean access$102(sun.security.provider.PolicyFile, boolean);
    static boolean access$202(sun.security.provider.PolicyFile, boolean);
    static boolean access$302(sun.security.provider.PolicyFile, boolean);
    static boolean access$200(sun.security.provider.PolicyFile);
    static sun.security.util.Debug access$400();
    static boolean access$500(sun.security.provider.PolicyFile, java.net.URL, sun.security.provider.PolicyInfo);
    static java.security.CodeSource access$600(sun.security.provider.PolicyFile, java.security.CodeSource, boolean);
    static java.lang.String access$700(sun.security.provider.PolicyFile, java.security.ProtectionDomain);
    static java.security.IdentityScope access$800();
    static {};
}

Sadly, my olde ascii2html script is not quite it… but I think you get the idea.

Go forth and dig them control codes, my friend! They exist only to serve your dread will.

Here is a link to a copy of the script just in case: http://brianin3d.googlepages.com/line_lite.sh


Dude has had this great link for a jillion years! http://www.fh-jena.de/~gmueller/Kurs_halle/esc_vt100.html, what a hero!

P.S.: Yes, I advocate EMACS-hateration. set -o vi or fight!

Comments (4)

Static Dependency Analysis

I recently started looking at a real mess of a project and want to start to try to understand how it was put together in terms of artifact dependencies.

Since it is at least using maven, my first thought was to use the poms to generate a dependency graph. After very little thinking, it was obvious that this was unreliable because of the potential for scenarios like this.

Say we have three modules A, B and C. The pom may declare a dependency from B to A (B->A) and from C to B (C->B). If in C there is a direct dependency to a class in A we won’t see that we have a dependency from C to A (C->A) because maven will compile using transitive dependency resolution. Of course, we should have an explicit dependency in the pom, but it is not required to build cuz C->B->A; only if the dependency from B to A (B->A) is cut, suddenly C fails to build.

I decided I needed to walk the source tree for each artifact. For each class, I would update a map that would map from full classname to artifactId and update the list of classes needed for the artifact based on the imports for the class.

Once all the artifacts have been evaluated, it’s time to create the artifact dependency graph and spit it out in so that Graphviz can create pretty (or horrific) pictures.

I hunted high and low for a package to parse java source code and finally settled on using PMD (http://pmd.sourceforge.net/) somewhat off-label for it’s AST parser.

Javadoc for it @ http://pmd.sourceforge.net/apidocs/net/sourceforge/pmd/parsers/Parser.html

I used PMD as as maven plugin back in the day so I was pretty confident it good kick that @$$!

As the Argentines say “let’s get it on!”

mvn archetype:create -DgroupId=javanal -DartifactId=importron -DpackageName=org.doom

 <dependency>
     <groupId>pmd</groupId>
     <artifactId>pmd</artifactId>
     <version>4.2.1</version>
 </dependency>

Since I am a lazy bastard, I will run it out of the AppTest.

I spanked this class up pdq:

    public class Artifact {
        String name
        Set< String > dependencies
        Set< Artifact > artifacts
    };

I will write about spanking classes later…

The app mostly fleshes out this map: Map< String, Artifact > classToArtifact which records which artifact a class (or package) lives in and the list of dependencies for each artifact, I will not waste your time with recursively walking a directory since it is very silly and a lot of fun I assume you will want to write it yourself, again. I think I’ve written this code about 27 times now.

Then, of course, there was a big fat ouch with the parser:

java.lang.NullPointerException
    at java.lang.String.indexOf(String.java:1564)
    at java.lang.String.indexOf(String.java:1546)
    at net.sourceforge.pmd.ast.JavaParserTokenManager.SkipLexicalActions(JavaParserTokenManager.ja
va:2049)
    at net.sourceforge.pmd.ast.JavaParserTokenManager.getNextToken(JavaParserTokenManager.java:200
0)
    at net.sourceforge.pmd.ast.JavaParser.jj_consume_token(JavaParser.java:9404)
    at net.sourceforge.pmd.ast.JavaParser.Statement(JavaParser.java:4013)
    at net.sourceforge.pmd.ast.JavaParser.BlockStatement(JavaParser.java:4159)
    at net.sourceforge.pmd.ast.JavaParser.Block(JavaParser.java:4120)
    at net.sourceforge.pmd.ast.JavaParser.MethodDeclaration(JavaParser.java:1401)
    at net.sourceforge.pmd.ast.JavaParser.ClassOrInterfaceBodyDeclaration(JavaParser.java:1070)
    at net.sourceforge.pmd.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:989)
    at net.sourceforge.pmd.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:500)
    at net.sourceforge.pmd.ast.JavaParser.TypeDeclaration(JavaParser.java:392)
    at net.sourceforge.pmd.ast.JavaParser.CompilationUnit(JavaParser.java:151)
    at net.sourceforge.pmd.parsers.Java15Parser.parse(Java15Parser.java:24)
    at org.doom.App.parseFile(App.java:57)

Sadly, this happened quite a bit:

pass=299=0.665924 fail=150=0.334076 total=449

33% of the time in fact, which I have to say is hugely disappointing. I’m guessin’ it’s due to classpath issues.

So I guess I should go cry.

Instead I will put on the big boy pants and write a very dumb “parser” to pull out the package, classname and a list of import statements for each source file. Of course that makes me want to puke, but it is either that, give up or find another parser.

So… for each source file, I updated the map to show where that class / package lived and for each import I added a dependency for the artifact.

Once I walked all the source code, I used the dependencies of each artifact to look up the artifact it depended on. I called this “resolveArtifactDependencies”

Finally, I dumped everything on in graphviz format so I could see the graph.

Sweet! example dependency graph

For bigger projects it looks even crazier!

Comments (1)