May 21, 2014
June 5, 2012
(Disclaimer: All opinions expressed herein are my own and do not necessarily reflect that of my employer)
Drag and drop seems like a great thing to have in a platform. Since Honeycomb, Android has had one... Unfortunately, it's severely lacking, and in some places just flat out broken.
For the past several months I worked on a customized Launcher app for a rather large phone manufacturer. We used the official google Launcher from the recently released ICS as a starting point.
Now, Android is a great platform; they've done a lot right. Some things though, like their Launcher code, isn't as quality as I would have expected.
We spent the first month refactoring several parts of the code. Pretty early on I had the bright idea to get rid of the monolithic Launcher.java and separate out the home and menu into two activities. I ended up just having a HomeFragment and a MenuFragment in the same activity, which worked much better, but the process resulted in me refactoring the drag and and drop to use what's provided by the platform.
Before this point, the Launcher used a transparent view called DragLayer that covered the window, intercepted events, drew the drag preview etc.
This method doesn't work when you want a drag to be started in one activity and end in another because the drag is tied to a view. (Long pressing an icon in the menu and dropping on home.)
The platform's drag and drop is much more robust in that it's handled completely separate from your activity. Your activity more or less hands off a surface to the window manager which takes it from there.
This has the great benefit of not having to manage dragging yourself. Unfortunately we also lost a lot of flexibility.
The first thing I ran into was you can't change the preview of what you're dragging after the drag has started. We needed to turn a dragged app icon red when hovering over a trash icon. It's simply not possible, at least not with the public API. Using a lot of reflection and manually exposing various functionality I was able to get around this limitation; but most people don't have the luxury of knowing the platform isn't going to change from underneath them.
Next up, views receive every event EXCEPT for start and end if they have a child that returns true on a start event. You can see more details on that bug here: http://code.google.com/p/android/issues/detail?id=25073
Or maybe I'm just using it wrong?
The next problem I ran up against was a lot trickier to figure out. Basically, it's possible to receive two drop events in a single drag. And before android 4.0.3 it would cause a crash that looks like this:
java.lang.IllegalStateException: reportDropResult() by non-recipient
at dalvik.system.NativeStart.run(Native Method)
More details on that can be found here: http://code.google.com/p/android/issues/detail?id=25061
There are several more bugs with androids platform drag and drop that other members of the team found. And then there are problems inherit with it operating in a separate process. (Such as if you want to animate your drag shadow once it's been dropped, but that's a rant for another day.)
Long story short; life is fun.
May 9, 2012
I found an implementation that did none of those. But it was fast, and close-ish to C++ friendly... ish.
It was open source so I encapsilated it all, converted all those pesky malloc and frees to... not malloc and frees (which indirectly fixed the memory issues) and changed it to output the result to something a little more useful.
And now I'm sharing the result with you. https://bitbucket.org/jlm/voronoi-c/
May 6, 2012
|Fuzzycraft - not minecraft!|
It's an interesting problem; sure it's just a bunch of cubes - but who wants to stop at a few thousand of them? You want a massive world where you can potentially see tens of thousands of theses blocks at a time. And due to its nature you're left without many of the techniques often used to optimize terrain rendering.
Sounds like a good opportunity to get a little more comfortable with OpengGL. Enter fuzzycraft-webgl; poorly textured terrain in all it's blocky glory! This ended up being horribly slow. More on that in a bit.
Trying out minecraft; the terrain seems to load very slowly. With my fairly high-end GPU I'm pretty sure OpenGL isn't the bottleneck here. Generating what blocks go where isn't slow either. (Test it by toggling the graphics options between fancy and fast; you can still see the chunks appearing one by one, oh so slowly) The only thing left is the process of building the geometry to send to the GPU.
I wanted to see if I could do better. Coffeescript was something I was wanting to try out and I always like to see how far WebGL can go. Turns out, getting good FPS was next to impossible with larger worlds. Generating the blocks of geometry to send to the GPU wasn't too bad; although to be fair, I had 8 cores chewing through it via web-workers.
Really, using OpenGL just works best in C. I was confident that it was possible to get it fast; both generating and rendering it. So I re-wrote it all in C++. There's really not a whole lot to say other than yes, it is very possible. There are still a few optimization I could do to make it run even faster. I may do them someday; but for now I've satisfied my curiosity.
So why does minecraft take so long to get those chunks of vertices to the GPU? I don't really know. Part of me wants to decompile minecraft's bytecode and find out. But I work with way to much Java as it is at my day job; and honestly, it's not a language I adore.
August 5, 2011
July 28, 2011
$ easy_install mark3 $ python -m mark3 < myfile.textOr used as a python module:
from mark3.markdown import markdown html_output = markdown(raw_text)I wanted a markdown to html converter for python3 that was lightweight and fast. So I created mark3.
Much to my surprise I was able to get mark3 quite a lot faster than existing libraries (~7x faster).
$ hg clone https://bitbucket.org/jlm/mark3 $ cd mark3 $ python tests/speed_test.pySee the README for details on how mark3 differs from the official markdown implementation.
July 9, 2011
WebGL is awesome and all, but it's far less portable. For example, my AMD card has been blacklisted on linux. So I figured I'd revisit trying to make a real-time game with 2D canvas.
Check out the game so far.
Off-Screen RenderingOff-screen rendering is both cheep and easy to use. Here I'm using it to render map tiles to a single image. Since the tiles are (mostly) static I don't need to be redrawing them individually each frame.
setInterval is not guaranteed to call at an exact intervalSo I already knew this, but I forget how much accurate timing matters for real-time games. To the point, calculate time-past yourself with the getTime function:
var dt = new Date().getTime() - last_time;Still use setInterval for scheduling logic and render functions, just don't expect the timeout values to be consistent with actual times.
The way to avoid this problem is to limit the number objects you create and then discard. Or an easy solution; just use Chrome. It's significantly better about it.
It's better on Google ChromeSimply put, Google Chrome is better for canvas based games. Dramatically better in some situations (or rather, Firefox is dramatically worse in some situations).
July 7, 2011
var buffer = document.createElement('canvas'); var buffer_ctx = buffer.getContext('2d'); // ... draw to buffer_ctx ...Then simply use our new buffer as an image:
main_ctx.drawImage(buffer, 0, 0);For example, I can use an off-screen buffer to apply an expensive bloom effect:
June 2, 2011
November 4, 2010
July 26, 2009
I recently started supporting Number Drill, my math drill software, for Linux a few days ago. Number Drill is a pure python program with the external dependencies of pygame, rabbyt, PyOpenGL and a few others. All of which were in the Debian and Fedora repositories.
I originally tried using cx_Freeze to make a binary to distribute. But I kept on running into major problems with this method. And as it ended up I would have to include a plethora of .so files (such as all of pygame and everything that it depends on, libssl and everything it depends on etc) just to avoid version conflicts that resulted in segfaults. Not to mention the resulting package ending up far larger than it should be.
That was about the time Matthew suggested just distributing the pyc files (gasp! I know, it's not open source) and letting package systems like deb and rpm handle dependencies. This method has ended up working almost perfectly. Both Ubuntu 9.04 and Fedora 11 have all the dependencies I require available. The resulting packages are very small (no binaries included, just the python byte code).
The only disadvantage is that it requires the latest versions of Ubuntu or Fedora (as of today) as they are the only releases that have new enough versions of my dependencies.
We wrote a bash script that automatically packages up a pure python program into both a deb and rpm. If you are interested in here it is: http://arcticpaint.com/static/blog/python_to_deb_rpm.sh
I believe that this method of packaging is even more effective in the open source world. It essentially just makes getting your program to run from source as easy as possible.
May 16, 2009
One of the major hindrances to using PyOpenGL before 3.0 was released (not python 3.0) was that packaging it with py2exe was next to impossible. Thankfully with the release of PyOpenGL 3.0 it is easy. Just include these two imports in one of your project files:
from ctypes import util
from OpenGL.platform import win32
That will tell py2exe which part of PyOpenGL to include. Otherwise you have to copy them over manually. Be sure to have the try and except around all win32 imports so your program remains cross platform.