Archive for the ‘javascript’ tag
State of the Engine
For various reasons, I’ve spent some time away from LxEngine coding over the last several weeks. I’ve decided to intentionally use this time away from the code to attempt to distinguish the forest from the trees and ramble about where LxEngine should be headed…
Script + Engine Driven
I believe I’d like to modify lxengine.lib into lxengine.exe. Instead of a library to build applications on, it should be an executable that is driven by a configuration file, scripts, and native plug-ins. A new app should be writable without any native C++ code. This mindset fits better with the original goals of rapid development as a priority. I’ve envisioning a manifest file suppling a list of shared and custom plug-ins (which are in turn a series of configuration files, scripts files, DLLs, and resource files) and a “main” script file to control execution. This seems like a better architecture for my goals.
Smaller Core, More Plug-ins
Physics, Sound, and many other utilities should be separate dynamically loaded DLLs. Lots of small DLLs is less efficient at runtime, but again – the goal of the project is easy, intuitive development rather than bleeding-edge performance. I need to constantly remind myself of this. I need to break out the non-core services into a set of plug-ins per the architecture described above.
It’s likely that Javascript and JSON support will be built into the core, as these will be the primary platform upon which further extensions can be built.
More but Smaller Samples
With a “no native code required” engine setup, I’d like to throw together a lot more minimalist examples. This fits better for testing purposes – not to mention it fits better with my erratic coding schedule.
Concurrent Architecture
I’d also like the LxEngine architecture to support a few high-level constructs more “natively” than directly coding in C++ or Javascript would. I want LxEngine to be different enough from a collection of standard libraries that the advantages (or disadvantages) of it are immediately apparent. I want it to heavily assume a concurrent, event-driven model.
The first-class concepts I’d like to include are:
States both in the form of sequences (context-dependent behaviors) and stacks (inherited and overridden behaviors). Concurrency, i.e. in the form of good threading support. Task support in the form of elegant coding mechanisms for large sets of small functional units. Coroutines, i.e. interruptible and resumable functions for spreading behaviors over a non-sequential time-period (useful for animation and AI scripts). Events – i.e. the engine should be almost entirely event-driven rather than sequential to better fit with the concurrency model.
Resource Manager
I’d follow the same “manifest file” approach with individual resources. A model, texture, script, etc. _cannot_ be loaded unless it provides a manifest file with licensing and other use / authorship metadata. I’d like to have part of the engine itself be a service to enumerate the proper credits and licensing information for any set of resources. Sure, this would be trivial to circumvent, but that’s not the goal; the goal is to make it easy for those developers who want to use open resources to automatically properly credit them.
Still a Development Platform
I still want LxEngine to be both an engine itself as well as a easy to use development environment / platform. Even if Bullet (for example) is no longer linked into the core engine, I want to retain LxEngine’s current scripts for pulling down the source release and building Bullet locally as part of the environment. I still want to support the use case where the third-party “auto-build” and configuration can still be used even if the lxengine core code itself is not used. Build and configuration is too much of a hassle on Windows. It shouldn’t be.
NaCL and the Web
Not sure exactly where I need to head in this direction. After some fruitful time working with Javascript in a purely web-based environment, I see a lot of advantages to immediately web-deployable work…but at the same time, I have not forgotten that C++ has some serious advantages. I don’t have a conclusion for where the native code base and the web code base should merge and if the answer is Google’s NaCl – but it’s an inevitably lingering question.
Ray tracing, Patterns, and the Web
(Caveat before I even say anything else: the ray tracer is unoptimized and really stresses the browser’s Javascript implementation. I recommend using Google Chrome for viewing it as Chrome is notably faster at the moment…)
I managed to reorganize the Javascript-based ray tracer such that it can be used as a JQuery plug-in: transform any CANVAS element into a ray traced scene. I then incorporated the 2D patterns library I’ve been working on for LxLang into the page. The result? An HTML page with multiple embedded ray tracers, rendering the various 2D procedural patterns onto a ray traced sphere. It’s really exciting seeing all these technologies working together.
Next up, I might work on using the HTML5 File API to add some image caching – the page load time for the below is a bit ridiculous.
Click here to view the ray tracing page. Or click the image below to get a static image of the results (admittedly, a much faster approach).
Ray Tracer Update
Further progress on the Javascript ray tracer…
The patterns library, written in LxLang and translated to Javascript, is now used as well as a new mappers library written in LxLang (dynamically translated until it is developed further).
LxLang Patterns Library
I’ve been doing a fair amount of work on the patterns lately. Admittedly, the page has only been tested with Chrome and I know there are a couple issues with Firefox but, for a prototype, this is fine.
Patterns Library
Several features I’ve added recently:
- Vertical scroll bar for manipulating pattern rotation
- Link to downloadable PNG of dynamically generated pattern image
- Converted all patterns to use LxLang (i.e. GLSL-like language) and dynamically generate the Javascript
- Integrated links to Google Closure Compiler optimized versions of dynamically generated JS
- Add UI settings to control resolution and multisampling
- Added several new patterns
Providing a Link to Generated Javascript
I’m working on LxLang a GLSL-like language that can be translated to Javascript, C++, and GLSL. The motivation is to avoid maintaining the same basic, low-level graphics functions in three different languages. The translator itself is written in Javascript, so the LxLang -> Javascript translation can occur live in a web page. However, I also wanted to provide a link to the translated source as a sort of “compiled” version, since I highly suspect anyone other than myself would be more willing to use the JS code than code written in some language they’ve never heard of.
Enter Data URI, a way to provide a link to that generated source without having to ever save it to a file. I’ve use this scheme before with the extremely nice toDataUrl method of the HTML5 CANVAS element as a way to generate downloadable PNGs from dynamically generated CANVAS graphics. So: I should be able to do this with generated javascript…
Data URI for Text
The solution I’m using is quite simple. Call Javascript escape on the source text, add a “data:text/plan,” prefix, and set that as the URL. Done.
var dataUri = 'data:text/plain,' + escape(source); $("#download-link").attr("href", dataUri);
The one downside that I haven’t been able to work past yet is that Chrome disables the “Save as…” option when you visit the resulting page. I don’t understand this. To download the file, you need to right-click save the link rather than visit the page and save that. Strange.
2D Patterns
Been working on a small Javascript library for generating 2D procedural patterns (with the ShaderBuilder in mind).
See the progress here or click on the image below.
Ray Tracing (Yet Again)
I obviously must enjoy writing basic ray tracers…
My recent realization has been that developing in Javascript – or more precisely in a browser-enabled language – makes a lot of sense for me at this point. Immediately demonstrable results along with a flexible, dynamic language for experimentation are higher utility than highly optimized offline compilation for my goals. At least for now.
So, I’m working on rewriting the LxEngine ray-tracer and ShaderBuilder in Javascript. I’m rather excited about the possibilities that a dynamic language will open. In any case, it’s still at a very early stage but I’m excited by the rapid progression:
Bookmarklets
I’d heard of bookmarklets, but never bothered to look into what they were. Life is full of complexities; there isn’t time to understand everything. Then I realized what a simple, wonderful tool I was missing:
Bookmarklets can be used run to client-side arbitrary javascript on any arbitrary page you want. Reformat, remove, extract, transform, you name it…
Animation? I’m Trying to Read Here!
Personally, I can’t stand animations and video when I am trying to read an article. They distract me. I mean completely. I can’t read the article. It drives me crazy when I am trying to read an article with content I’m legitimately interested in and a video is flashing on the side of the screen.
My usual solutions are the embarassingly un-technical approaches of either moving the sidebar ad off-screen or refreshing the page hoping to it will fresh to a static ad. If that fails, out comes Chrome Element inspector to remove the offending element.
In general, I do understand the need for ads on websites so I’m not really looking for full ad blocking software. However, I do wish for the times it’s really driving me crazy that I could automate the process of making distracting animations go away.
IFRAMES be Gone!
Introducing “Remove IFRAMES” an immensely simple bookmarklet that took about 12 seconds to author that removes all iframe elements from a page with the click of a button. Annoying video ads on a page? Most likely they’re embedded in iframes. Click of a button, they are gone. Back to reading the actual content of the article.
Create a new bookmark, add the code below as the link URL, go to a page with iframes, click on the bookmark…and voila!
javascript:(function(){var a=document.getElementsByTagName('iframe');for(var i=0;i<a.length;++i){a[i].setAttribute('src','');}})()
Or simply create a bookmark to this link: bookmarklet
Sure, it doesn’t solve my whole I-want-nothing-animated-on-this-page problem, but it illustrates the idea of how wonderfully simple and useful bookmarklets are.
Readable
A much better example would likely be Readable, a simple bookmarklet that reformats a page to be – you guessed it – more readable. Brilliant. Simple. Brilliant because it is so simple.
Also worth noting, if you look at the bookmarklet source for Readable is the fact that it essentially stores the options in the bookmarklet itself, but store the crux of the script in a proper script file hosted elsewhere (so you don’t have to cram all the source into the bookmarklet url text itself).
Needless to say, it was Readable that clued me in that bookmarklets are actually a potentially wonderful tool for customizing web browsing to the way I like it. It’s exactly the kind of mini-extension without having to write a full extension that I’ve been looking for!
I’m sure this is all elementary to someone who has come across bookmarklets before, but for me, this was the introduction!
The Web Browser as a Build System
This post can largely be qualified as daydreaming, or maybe just hoping aloud. In any case, here’s a look at some browser changes that I think could revolutionize the web.
The best part about this is that there’s absolutely nothing new being proposed below. It’s about taking existing ideas and fitting them together in a way that would work efficiently.
A Standard Browser Bytecode/Virtual Machine
Create an open ISO standard bytecode. Create a sandboxed virtual machine to run the code.
Now the browser can run script via Javascript or via any language that can be compiled into that byte code. Share the runtime environment so that chunks of Javascript and bytecode can be interweaved.
Wait, isn’t that what Java was? Key difference: integrate the DOM with the virtual machine. Honestly, that’s the key difference. You don’t end up with a disparate Java applet sitting in a hosted rectangle, essentially disconnected from the rest of the page, with a totally different looking UI. No, you get the simplicity of HTML5 for the UI because the virtual machine is seamlessly part of the page. Don’t reinvent what makes HTML so popular: use it instead.
Wait, emscripten already does this. Yes! In many ways it does, and it’s a fantastic idea. The big differences are that I’d love to see the LLVM interpreter as a standard part of the browser – plus, I imagine it’d be more efficient to embed LLVM’s interpreter into the browser native code than interpret the bytecode via a virtual machine running through the Javascript interpreter. Let’s get native support for integer types running in the VM.
Wait, what about Google’s NaCl? To me, it seems a lot of excellent technology but not put in its optimal place. Where is the advantage to running native binaries directly rather than adopting a standard bytecode instead since those native binaries need to be compiled through a custom toolchain anyway? Also, NaCl code can’t directly access the DOM and, in my mind, that’s critical.
Base it on LLVM bytecode
Let’s make it based on a subset of LLVM’s bytecode. Update the version via committee as the various parts stabilize and are agreed to be “good”. Let the virtual machine evolve to handle the needs of future web programming, rather than bloating the Javascript language into a do-all language.
Perhaps Microsoft’s .NET CIL is sufficient. I don’t know if it is “open” enough or not, though from what I’ve read it does seem pretty solid from a technical perspective.
The question really is: are there enough quality, free tools for generating the bytecode to hit a critical mass such that more quality tools start to be developed around it?
Using C++ on the Web Would Be Possible
This is the part I like, since I think in many ways, C++ is the best general purpose, production-code language.
Clang compiles C++ code into LLVM bytecode. If the browser can safely run sandboxed LLVM code, it can now run C++. Use clang on the developer machine to compile C++ code into bytecode, host the bytecode on the web, run the bytecode. (Ensuring simple Clang installers for all major platforms would certainly be a helpful side project here.)
Some run-time linking will be necessary on the part of the VM to hook that bytecode into the runtime environment (i.e. the DOM), but theoretically nothing overly burdensome has to happen.
(As a slight aside, don’t allow “unsafe” or “trusted” scripts to run outside the sandbox and access the machine resources directly. Just don’t. Ever. If hardware resources need to be exposed, let them be exposed as they are now by advancements in the web standards as WebGL, the HTML5 File API, etc. are being exposed. Use currently existing plug-in mechanisms outside the standard scripting environment if you really need to reach beyond the run-time environment. These will be available to scripts, as the DOM is, but not implemented as scripts. Keep the script environment itself clean and always sandboxed.)
Using C++ as a Web Scripting Language Would Be Possible
Now, Clang is self-hosting, so compile Clang (or a subset of it) to LLVM bytecode. The web page environment can now have the moral equivalent of a “compileCpp(source)” function.
Use a trivial bit of Javacript to transform script tags of type=”text/C++11″ into LLVM bytecode – and voila, C++11 can now be used as an interpreted scripting language.
Languages like CoffeeScript or even LESS already do a similar transformation from a new language to a browser standard; however, rather than targeting a language designed for direct programming, target a generalized bytecode intended from the start to be a target of other language transformations. (Things being used for what they were designed for tend to be more efficient.)
The potential uses for C++ on the web seem enormous to me: prototyping native code in a dynamic environment, a sandboxed development environment for new C++ modules, live unit tests of code bases, rapid previews of code modules and segments, live testing during code reviews, finally a semi-standard cross-platform UI solution for C++, shared code between web and desktop versions, a strict typing language to add robustness to critical production web code, etc.
The list of uses almost seem self-evident to me. (Perhaps I like C++ too much.)
Browser Caching Enhancements
I’m not an expert on browsing caching capabilities, but the above assumes either uploading the bytecode or compiling the C++ code on the web page load.
Let’s ensure the browser has sufficient logic to write out a compiled version of the C++ code to a cache (on a per-section basis, i.e. like O/OBJ object files). Visit the page the first time and wait while it compiles; visit a second time and it loads the compiled code from the cache (and probably only does some minimal linking). I mean literally the first visit to the server and the second visit: cache this on the server, not per-user.
Of course, some sort of “trusted user” mechanism would need to be in place if the compilation is occurring on the client-side and the caching being done on to a shared server-side. (Definitely a solvable problem – even if means something like invoking a PHP script in a password protected directory to write out the cached file; but it would be more fluid to have a standardized browser mechanism for this.)
Next, let’s make sure those caches work with CDNs (content delivery networks). There’s no reason to host the standard C++ library on my site and have that compile separately for every page that uses it. Instead, the script src tag references a library version hosted on a CDN where there will be a cached, compiled copy already available.
Also, once the idea of CDNs comes into place, the problem of “dependencies” becomes much simpler. Add a URL to the library on the CDN: never worry about compiling or installing any dependency. The URL would likely implicitly or explicitly contains the version number, compiler used, compile flags, etc. CDNs could even host the compilers they used to absolutely ensure no ABI (application binary interface) issues between their hosted code and locally hosted code.
A Web-based Distributed Compiler/Make
Now simply think of the above in broader terms: cache on a module-by-module basis, add in dependencies between segments of code, mark everything with version numbers, cache on CDNs…and it’s not much of a stretch to think of how a full Make system can be hosted in the browser (i.e. via a script/bytecode, not directly in the browser source) and how CDNs start making the whole internet start to act like a large distributed compiler.
Because this is all distributed, it’s not really bloating what the web browser does. A web page might have only a couple dozen lines of custom code. The rest is pre-compiled code sitting out there on CDNs in the same way stock photography or massive databases are sitting out there hosted on high-end servers elsewhere.
With CDNs and caching, “compile-time” should become a non-issue for the end-user; download time is the only bottleneck – and heck, that’s already true for native apps today.
A Bit of Client-Side Caching
Let’s also reserve a chunk of disk space for client-side caching of LLVM-to-native code caching. The browser can work with the VM’s JIT to cache optimized native code for the bottleneck sections of the bytecode. This should speed up the most frequently used apps to near natively-compiled code speeds (see current C# versus C++ performance benchmarks if you want a estimate of “near”).
For safety, simplicity, and security, let’s keep any cached native code local: don’t host anything that runs outside the safety of a sandbox on a CDN. (Sure, NaCl could run the native code in a sandbox as well, but let’s keep things simple.)
Other General Languages and Domain-Specific Languages
Now repeat this process for languages other than C++. Anything that can be compiled to LLVM bytecode can safely run on the web. Anything language that has a compiler that can be compiled into LLVM bytecode can be run on the web.
Any language that has a compiler hosted somewhere on the web can be used (no worrying about if the user has
the right version of Python installed or not!). The barrier to entry for domain-specific languages drops notably.
<script compiler=’http://cdn.somesite123.org/hosted-compilers/python-2.7.0′ src=’mycode.py’ />
<script compiler=’http://cdn.somesite123.org/hosted-compilers/joelanguage-0.2.3′ src=’dslcode.txt’ />
An Quick Aside on Code Reuse
I’m convinced that code reuse is dependent primarily on how easy it is to reuse the code.
Having an explosion of different languages on the web and of different language versions will not undermine code reuse. Rather, if including large, production code modules was as simply as adding support for JQuery via a CDN – then heck, a lot more code reuse would happen. Forget the build dependencies, install locations, etc. that can add serious overhead to using a third-party library (especially on Windows). All this disappears. Sure the specific locations for a particular compiler, library, etc. might not be standardized but because the same instance is shared across the web that itself making that single instance a standard: it’s going to be there for anyone who connected to the internet.
Standards make things easier to use: and a standard virtual machine does not create a standard for authoring code but rather creates a standard for using existing code. I conjecture that increasing the number of languages available on the web in this manner would actually drastically increase code reuse on the web.
These are Not New Ideas
Obviously, nothing above is new. I’ve mentioned Java, .NET, NaCl, etc. and I’m sure others can point out much earlier projects exemplifying these ideas.
I think one of the major strengths of Unix was something Windows still has failed to realize: include a compiler – that is always there – with the operating system and far more people will build tools and applications for it. (To be clear: I’m using “operating system” here to mean the full default operating environment, not just the kernel.)
The browser is becoming in many ways like an OS. What I’m envisioning is creating a standard “tool-chain” that’s always there in the browser. Look how successful simply having a standard interpreter in the form of Javascript has become. Now imagine if you took the good ideas behind Java, .NET, CDNs, Make systems, etc. and provided that instead of just Javascript.
Again, nothing here is new. However, the idea of connecting all these ideas into a simple, usable, coherent, and standard system seems so tantalizingly within reach at this point in the evolution of the web. It’s agitating. It’s exciting.
The web browser as a build system: I can hardly imagine how the web and computing world would change.
Postscript: Interested?
Think this is a great idea and have the discretionary funds to hire me to work on this?
I’m only half joking
Javascript Closures
I am very much a fan of C++11 lambda functions. They’re very useful and make perfect sense to me. In particular I like the “=” and “&” notation to specify if variables from the outer scope are (effectively) copied by value or passed by reference to the closure. Pass by value and pass by reference are fundamental parts of C++ and make good sense to me.
However, for some reason I simply wasn’t grokking how the equivalent functionality works in Javascript. Everything seems to be a reference: how do I “pass” something by value to a function object in Javascript? And even knowing how the answer, why is that?
The Question
Let’s start with a fabricated simple example. It creates 10 functions, each of which appends a number to the end of a result string.
Result:
Analysis: As the results should (it’s run live in your browser, so hopefully they are as expected!) indicate, the above code results in a string of “10″ repeated 10 times. Why is this? Because “i” in the inner function is a reference to the “i” from the outer scope. It is not a copy or passed-by-value into the inner scope. There’s only one object ever named “i” and it’s value is 10 at the time the functions in the “funcs” array are evoked.
Now the question is, how do we get the above code to result in “0 1 2 3 4 5 6 7 8 9″?
The Answer
Let’s quickly look at the answer (which you could probably find in lots of places on the web, but I never found a satisfactory accompanying explanation). To get the value “copied” into the function, you need to wrap the function in outer function invokation which passed in the variable as an argument:
var n = ...;
var f = function() { /* code using n */ };
var g = (function(n) { return function() { /* code using n */ }; })(n);
In the above if “f” is called, it will use the value of “n” at the time that f is called – since it holds a reference to “n”.
In the above if “g” is called, it will use the value of “n” at the time that g was created – since the inner function actually holds a reference the function argument “n”, not the outer n.
Why? In short, when an object is passed as an argument to a function, a shallow copy of that object of the object is made. Thus the inner function refers to the copy at the time of the invokation of the outer function rather than a referring to the object in the original outer scope.
A little less elegant as compared to C++, but the pattern works and allows you “pass by value” into the closure.
Revisiting the Example
Using the above information, let’s now modify the example to print the result we want:
Result:
The key difference between this example and the original example:
- In the original example, there was 1 object created called “i”
- In the second example, there were 11 objects created called “i”
In the first example, each function in the “funcs” array refers to that single object called “i”. In this example, each function in the “funcs” array refers to a different object that was created temporarily when the outer, wrapper function was invoked. This ensures that the value of loop variable “i” at the time of the function creation is retained for use when the function is later invoked!





