Tomfoolery with Lua

Posted on Feb 23, 2008 cplusplus lua programming

I done a fair but of hacking around with the lua scripting language in the past, and while my motives for doing so were oftentimes questionable the fact remains that I learnt a few tricks that make embedding and using it easier.

As a language lua takes a "less is better" approach and instead provides the tools for you to extend its functionality rather than bloating the core distribution with stuff that isn’t really necessary. As such you’ll need to add some of that bloat yourself :) Henceforth I will be making the dubious assumption that you are familiar with the basics of embedding lua with c++ applications and get right into the meat of things.

Getting a lua stack trace

when a lua script encounters an error you can get the error message from the top of the lua stack by calling

lua_tostring(luaState,-1);

however wouldn’t it be more useful to get a full stack trace to give you more context as to where and why the error occurred? Luckily lua includes a nifty mechanism for hooking into events during script execution and while these can be used for all sorts of extremely cool and powerful things, I’ll be showing how you can use these events to build a call stack.

firstly lets create a list of strings (we’ll be using it as a stack…),a new lua state and hook up some events to it. The lua _sethook function allows you to hook in a number of events and provide a callback function to call when these events occur. In this case we want to be notified whenever a function is called (LUA_MASKCALL) or whenever a function returns (LUA_MASKRET)

std::list<std::string> _stack;
_state = luaL_newstate();
lua_sethook(_state,&FunctionHook,LUA_MASKCALL | LUA_MASKRET,0);

This should allow us to build up a callstack by pushing information on the last called function onto a stack, then popping the top off the stack every time a function returns, simple eh? now on to the implementation of the callback function

void FunctionHook(lua_State *l, lua_Debug *ar)
{

//fill up the debug structure with information from the lua stack
lua_getinfo(l, "Sln", ar);
//push function calls to the top of the callstack
if (ar->event == LUA_HOOKCALL) {

std::stringstream ss;
ss << ar->short_src << ":"

<< ar->linedefined << ": "
<< (ar->name == NULL ? "[UNKNOWN]" : ar->name)
<< " (" << ar->namewhat << ")";

_stack.push_front(ss.str());
}
//pop the returned function from the callstack
else if (ar->event ==LUA_HOOKRET) {

if (_stack.size()>0)
{
_stack.pop_front();
}
}
}

This function gets automatically called whenever a function is called or a function returns. Each time a call event takes place we push some information regarding that function (name, line number etc…) onto our call stack, and every time a function returns we pop it from the call stack.

So when a lua script encounters an error the contents of the _stack variable will contain a full stack trace up until the point of the error, neat eh? (the cryptic "Sln" parameter for the lua_getinfo function specifies what fields of the lua_Debug struct to populate, see the lua reference manual for more information if you’re interested)

NOTE: You’ll probably only want to enable this stack tracing for debug builds of your applications as there is a performance hit in hooking into these lua VM events.

At some stage in the future I’ll blog about my c++ LuaState class which wraps up the process of creating, loading, running, debugging and cleaning up lua scripts in a nice OO fashion but until then enjoy your new-found stack tracery.

why do people split movies into 700mb blocks?

Posted on Jan 19, 2008 dotnet programming

For the love of god people, its 2008, I haven’t burned a CD in at least 3 years, we all have hundreds of gigabytes of disk space, USB flash drives which hold multiple gigabytes, and high speed wireless LAN connections in our homes… So why is it that people still distribute movies split into 700mb blocks? who actually needs a movie to fit on a CD nowadays?

For me one of the most annoying things in the world is for a great movie to stop halfway through, right when you’re immersed in the story and atmosphere, abruptly forcing you back into the mundane drudgeries of reality to get up off the couch, trudge over to the PC, find the second movie file and hit play. Its not that its a huge inconvieniance, its just that with today’s storage technology we can quite happily distribute movie files in one multiple gigabyte file, using the 700mb CD storage limit is completely unecessary.

So anyway, whenever I get a movie split into ridiculous 700mb blocks I insist on merging them into one single file, VirtualDub is a great tool for this as it allows you to do a direct stream copy and append the second file to the first without having to re-encode the video or audio streams. This turns a job that can take upwards of an hour down to a few minutes and also means there is no loss of quality in the source material.

However I am a fan of foreign language films which more often than not come with external subtitle files (usually in .srt format) This means that if you want to merge the video files together you have to do the same for the subtitle files. The problem with this is that its a serious amount of work to do it by hand, so to ease my pain (and possibly yours) I wrote a tool which merges .srt subtitle files together. All you have to do is specify the two subtitle files to merge and also specify the first movie file (so the program knows how far to offset the subtitle timings in the second subtitle file by).

The source for this program is available here

Hasta Luevo.

Mobile torrentry

Posted on Jan 14, 2008 j2me programming

After owning a motorola v3x for the better part of a year it finally dawned upon me the other day that it runs Java applications therefore because I know java (well I hadn’t written any in over a year, but hey its like learning to ride a bike right?) I could write an application for my phone. Turns out it was pretty easy to do, I just downloaded the Motorola Java ME SDK v6.4 for Motorola OS Products which includes a plugin for the java eclipse 3.2 IDE and I was able to use the software simulator (image below) to debug and test before deploying onto an actual mobile device.

Untitled-1

So with everything set up I needed an idea for an application, my first thought was toward some sort of remote control device for my PC, this idea eventually morphed into a mobile monitor/control for bittorrent downloads. Since my phone is capable of making http requests It would be a matter of writing or finding a server application that my phone could interact with which would in turn control the bittorrent client.

I already have utorrent set up as a service on a dedicated machine, so It was a matter of finding something a way to expose utorrents functionality to the web, luckily for me utorrent has a webUI component that allows you to view and control your torrents via a web page from anywhere in the world. So far, so good, but it gets even better. The webui also has an API which returns data in JSON format.

So with utorrent and the webui all set up (heres a good guide here) all I had to do was write an application which called the utorrent API and boom, remote torrent action on your mobile! Of course it was easier said than done, but on the whole J2ME was pretty easy going and it didn’t take long to write the mobile client. The most difficult part was writing a J2ME compatible API for accessing the utorrent webui web services. Below are a few screenshots of the finished application.

Untitled-3 Untitled-2

You can download the application here The source is also available here

c# project dependancy visualization

Posted on Dec 16, 2007 dotnet programming

Have you ever wanted a way to quickly visualize the overall architecture of a c# solution in the form of some sort of pretty diagram?

Well I had that thought yesterday, and figured that there must be some free tool out there that can take a solution file or directory and build a graph of all the underlying project files and dependancies. However to my dismay I found that there were no such tools (or they were commercial products or were completely over the top for what I wanted) so I decided to roll my own :)

The end result is an app which builds a graph of all the projects and dependancies in a directory (plus its subdirectories) as well as the relative sizes of those projects. In addition the graph is fully moveable by the mouse and all the nodes and points behave with realistic physics (I reused my Tarantula physics engine developed a while back)

dependancyAnalyzer

The app is written in c# 2.0 and is available in binary or source code form (under the conditions of the MIT license)

Download the source here

Mapping boost::signals to .net events

Posted on Nov 24, 2007 cplusplus programming

A while back I blogged about wrapping native c++ classes inside managed .net classes using c++/cli, and while that blog detailed wrapping up a class with methods and properties I did not go over how to map across boost::signal’s to the .net event model.

Below we have a native c++ class which has the ability to copy files and notify listening classes of it’s progress in doing so.

Unmanaged Class Interface

class FileCopier
{

public:
typedef struct {
long BytesCount;
long BytesCopied;
std::string CurrentFile;
} CopyProgressEvent;

typedef boost::signal<void (CopyProgressEvent)>

CopyProgressEventHandler;//progress callback signature

/**
add a listener to copy progress events
*/

void AddCopyProgressListener(CopyProgressEventHandler::slot_type listener);

private:
CopyProgressEventHandler _handler;

};

The AddCopyProgressListener class accepts a pointer to a suitable callback function that conforms to the signature void(CopyProgressEvent) and adds that callback to the event handler

which can be used to notify all listeners of the event. All well and good so now to wrap it up in .net goodness using c++/cli. We’ll be using the managed wrapper class I wrote in a previous blog entry (here) as the basis for the file copier wrapper.

The full interface for the wrapper class is shown below, in order for this to work we have to duplicate the copyProgressEvent in a managed class and supply our own delegate class and event for managed listeners to subscribe to. The notifyListeners method is what takes an unmanaged copyProgress event, wraps it up in its managed equivalent and passes it off to the event handler

Managed Class Interface

public ref class
ManagedCopyProgressEvent {

public:
long BytesCount;
long BytesCopied;
System::String^ CurrentFile;
};

public ref class ManagedFileCopier:
ManagedEntityBase<FileCopier>
{
public:
delegate void CopyProgressEventHandler(ManagedCopyProgressEvent^ args);
event CopyProgressEventHandler^ OnCopyProgress;

ManagedFileCopier();

public private:
void NotifyListeners(CopyProgressEvent args);
};

Okay, so the interface makes sense to any .net classes wanting to subscribe to the copyprogress events, but how are we going to do the behind the scenes routing of the boost::signal event such that notifyListeners gets called at the appropriate times? If we were working with native c++ classes we can happily used boost::bind to turn the notfyListeners member function into a suitable callback for the signals event, however because NotifyListeners is part of a managed class, this approach doesn’t work so we have to take a slightly more roundabout approach.

The notifier proxy

This is where the function below comes in. Its purpose is to provide a valid function for boost::bind to use as a callback, but also to keep a reference to our managed class so that NotifyListeners can be called when a boost::signals event is fired (This should hopefully make more sense when we actually hook all these pieces up in the managed classes constructor)

void NotifyProxy(gcroot<ManagedFileCopier ^> this_,CopyProgressEvent args) 
{
this_->NotifyListeners(args);
}

Putting it all together

The implementation of the constructor is where the notifier proxy gets hooked up to the unmanaged boost signals event. Using boost::bind we use the notifyProxy function and the instance of the managed class to create a callback for the unmanaged boost::signal.

ManagedFileCopier::ManagedFileCopier() : ManagedEntityBase(new FileCopier(),true) 
{
NativeEntity->AddCopyProgressListener(
boost::bind(
NotifyProxy,
gcroot<ManagedFileCopier^>(this),
_1)
);
}

The implementation of the NotifyListeners method is pretty straightforward, we create a new instance of a managedCopyProgressEvent then copy the unmanagd attributes over before passing the object as an argument to the .net OnCopyProgress event.

void ManagedFileCopier::NotifyListeners(CopyProgressEvent args)
{
ManagedCopyProgressEvent^ mArgs = gcnew CopyProgressEvent();
mArgs->BytesCopied = args.BytesCopied;
mArgs->BytesCount = args.BytesCount;
OnCopyProgress(mArgs);
}

So there you have it! thats how you can route events from the boost::signals library though to managed .net code. Below is an example of some c# code using the managed class we’ve written.

ManagedFileCopier fc = new ManagedFileCopier();

fc.OnCopyProgress += new ManagedFileCopier.CopyProgressEventHandler(OnCopyProgress);

void OnCopyProgress(ManagedCopyProgressEvent args)
{
...
}

Latest tweet