Ruben Laguna's blog

Accessing C++ Objects From Lua

Continuing the post about lua integration with C++. Now to more serious stuff. Let’s try to write a wrapper for a std::list<int>. Imagine that you have a std::list<int> in your C++ that you want to share with the Lua enviroment. So both C++ and Lua can access the list.

Keep in mind, that I’m going to use a std::list<int> as an example but you could apply the same idea to any other type: user-defined or builtin.

Basics

First, let’s get the Makefile in place

1
2
3
4
5
6
LUAHOME=$(HOME)/tmp/lua-5.2.1/src

all: sampleluahost

sampleluahost: sampleluahost.cpp
  g++ -g sampleluahost.cpp -llua -L$(LUAHOME) -I$(LUAHOME) -o sampleluahost

Lua script

1
2
3
4
5
6
7
8
9
10
11
12
13
function entries(arg) -- iterator
  return function()
         return arg:pop();
         end
end

for i in entries(the_list) do
  io.write("From LUA:  ", i, "\n")
end

for i=1,10 do
  the_list:push(50+i*100);
end

This script when executed will empty the_list printing its contents and will fill it again with new content. That will illuestrate that Lua can access the underlyint std::list<int> backing up the_list.

Note that we use the colon notation to call methods on the_list. So when I write arg:pop() it’s tranlated to arg.pop(arg). The first argument to the function will be the object itself (Think on that argument like the implicit *this in C++ methods or self argument in python).

Note: that I wrote an iterator for the list in lua. That is a function that returns a closure. the for will call this returned function over and over until it returns nil.

The arg:pop() will pop a element from the front of the std::list<int> and will return nil when the list is empty.

The C++ host application

++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <lua.hpp>
#include <iostream>
#include <list>
#include <assert.h>

extern "C" {
  static int l_list_push(lua_State *L) { // Push elements from LUA
    assert(lua_gettop(L) == 2); // check that the number of args is exactly 2 
    std::list<int> **ud = static_cast<std::list<int> **>(luaL_checkudata(L,1, "ListMT")); // first arg is the list
    int v =luaL_checkint(L,2); // seconds argument is the integer to be pushed to the std::list<int>
    (*ud)->push_back(v); // perform the push on C++ object through the pointer stored in user data
    return 0; // we return 0 values in the lua stack
  }
  static int l_list_pop(lua_State *L) {
    assert(lua_gettop(L) == 1); // check that the number of args is exactly 1
    std::list<int> **ud = static_cast<std::list<int> **>(luaL_checkudata(L, 1, "ListMT")); // first arg is the userdata
    if ((*ud)->empty()) {
      lua_pushnil(L);
      return 1; // if list is empty the function will return nil
    }
    lua_pushnumber(L,(*ud)->front()); // push the value to pop in the lua stack
                                      // it will be the return value of the function in lua
    (*ud)->pop_front(); // remove the value from the list
    return 1; //we return 1 value in the stack
  }
}
class Main
{
public:
  Main();
  ~Main();
  void run();

  /* data */
private:
  lua_State *L;
  std::list<int> theList;
  void registerListType();
  void runScript();
};

Main::Main() {
  L = luaL_newstate();
  luaL_openlibs(L);
}

Main::~Main() {
  lua_close(L);
}

void Main::runScript() {
  lua_settop(L,0); //empty the lua stack
  if(luaL_dofile(L, "./samplescript.lua")) {
    fprintf(stderr, "error: %s\n", lua_tostring(L,-1));
    lua_pop(L,1);
    exit(1);
  }
  assert(lua_gettop(L) = 0); //empty the lua stack
}

void Main::registerListType() {
  std::cout << "Set the list object in lua" << std::endl;
  luaL_newmetatable(L, "ListMT");
  lua_pushvalue(L,-1);
  lua_setfield(L,-2, "__index"); // ListMT .__index = ListMT
  lua_pushcfunction(L, l_list_push);
  lua_setfield(L,-2, "push"); // push in lua will call l_list_push in C++
  lua_pushcfunction(L, l_list_pop);
  lua_setfield(L,-2, "pop"); // pop in lua will call l_list_pop in C++
}

void Main::run() {
  for(unsigned int i = 0; i<10; i++) // add some input data to the list
    theList.push_back(i*100);
  registerListType();
  std::cout << "creating an instance of std::list in lua" << std::endl;
  std::list<int> **ud = static_cast<std::list<int> **>(lua_newuserdata(L, sizeof(std::list<int> *)));
  *(ud) = &theList;
  luaL_setmetatable(L, "ListMT"); // set userdata metatable
  lua_setglobal(L, "the_list"); // the_list in lua points to the new userdata

  runScript();

  while(!theList.empty()) { // read the data that lua left in the list
    std::cout << "from C++: pop value " << theList.front() << std::endl;
    theList.pop_front();
  }


}

int main(int argc, char const *argv[])
{
  Main m;
  m.run();
  return 0;
}

The idea is to set up the basic lua enviroment thought the luaL_newstate and luaL_openlibs.

Then we create a metatable with luaL_newmetatable. A metatable is just a regular table that can be associated with lua values such as userdata. The metatable is where Lua goes to search for metamethods. You can see the list of available metamethods in Lua Reference. In this case we define the metamethod __index, which is the metamethod used by Lua when in cannot find a given index in a table or userdata. So imagine that a is a userdata and we type a.elem. a has no elem in it so it invokes __index on a’s metatable to see what to do. It’s kind of method_missing in Ruby if you are familiar with Ruby. Now the __index metamethod it’s a little bit special in the sense that I doesn’t need to be a method/function at all. If Lua finds out that the __index field of the metatable is actually a table and not a function it will just use that table to find the key. So going back to a.elem example, that will be translated to getmetatable(a)["__index"].elem.

We will use the "ListMT" metatable to hold the methods for lists. We associate the metatable entries for push and pop with two static C functions l_list_push and l_list_pop. This functions must be of type lua_CFunction. that is they should take a lua_State * as paramter and return an integer. That’s how the Lua communicates with C++, via the lua_State and its stack.

The functions themselves are quite straighforward. They must be defined as extern "C" because Lua is compiled as a C library and it will call all the lua_CFunction with a C linkage (that determines the order in which the function parameters will be pushed into the machine’s stack, etc.) so we need to make sure that the function that we are generating here can be called from C.

The function are designed so that the first parameters is always the “object” in this case a userdata of type “ListMT”. The lua function luaL_checkudata will check that the metatable of the userdata matches and it will provide the pointer to the userdata. When Lua call the funciton the arguments to the functions are always pushed into the stack so that the first parameter lands on the stack position 1. So arguments are easy to address.

Finally the Lua resources are freed with lua_close.

Output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Set the list object in lua
creating an instance of std::list in lua
From LUA:  0
From LUA:  100
From LUA:  200
From LUA:  300
From LUA:  400
From LUA:  500
From LUA:  600
From LUA:  700
From LUA:  800
From LUA:  900
from C++: pop value 150
from C++: pop value 250
from C++: pop value 350
from C++: pop value 450
from C++: pop value 550
from C++: pop value 650
from C++: pop value 750
from C++: pop value 850
from C++: pop value 950
from C++: pop value 1050

Things to remember

  • Understand userdata, metatables and metamethods
  • Lua and C++ communicate though the Lua stack
  • check the number of arguments with `assert(lua_gettop(L) == x);
  • empty the lua stack or assert that it’s empty where do you know that the stack should be empty

Sublime Text 2 Integration With RVM and Rspec: Take Number 2

On a previous post I’ve talk about how to get Sublime Text 2 to honor the .rvmrc files when executing both regular ruby and rspec.

The solution described there, as pointed out in in the comments, is non-optimal.

Correcting the old post seemed like a lot of work so I will prefer to post something new.

Ok, so you are using Sublime Text 2 and you can use Cmd-B to execute ruby code, but that ruby code won’t be executed using under the environment dictated by the .rvmrc in the project which is a pity. The same goes for RSpec, where you usually want to use bundle exec rspec in addition to .rvmrc.

I’m going to talk first on how to get regular ruby + RVM from Sublime Text 2 and then I’ll jump onto executing RSpec together with RVM and Bundler from Sublime Text 2.

Ruby

Well this one it’s very easy. You just need to update ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/Ruby/Ruby.sublime-build to look like

1
2
3
4
5
6
7
8
{
  "env":{
      "PATH":"${HOME}/.rvm/bin:${PATH}"
  },
  "cmd": ["rvm-auto-ruby", "$file"],
  "file_regex": "^(...*?):([0-9]*):?([0-9]*)",
  "selector": "source.ruby"
}

The env part will add rvm-auto-ruby into the $PATH and the cmd will execute rvm-auto-ruby yourfile.rb when you press Cmd-B. You and add options in between rvm-auto-ruby if you want, like this `”cmd”: [“rvm-auto-ruby”, “-S”, “$file”].

So that’s it. Now you can just Cmd-B a file and it will use rvm-auto-ruby to run it and that will use the settings in the .rvmrc file, running the specific version/flavor of ruby of your choice (MRI-1.8.7, MRI-1.9.3, etc).

Rspec

If you are using RVM, it’s very likely that you are using bundler too. And then, executing your test from Sublime Text 2 won’t work as expected because you really need to execute bundle exec rspec instead of just rspec to make sure that all the gems versions specified in in your bundle (Gemfile) are visible in your enviroment prior to executing rspec.

In order to do that you need to do some modification to the package that you use to run the RSpecs

Sublime Package: RSpec

If you use RSpec package (You can install it with Package Manager) then you can run your rspec with Cmd-B (asumming that you changed already the builder of your project to Rspec, with Tools/Build System/RSpec). But that will execute just rspec without RVM and without bundler. So to get RVM and bundler into play change the ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/RSpec/RSpec.sublime-build like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "env":{
      "PATH":"${HOME}/.rvm/bin:${PATH}"
  },
  "cmd": ["rvm-auto-ruby","-S", "bundle", "exec", "rspec", "-I ${file_path}", "$file"],
  "file_regex": "# ([A-Za-z:0-9_./ ]+rb):([0-9]+)",
  "working_dir": "${project_path}",
  "selector": "source.ruby",

  "windows":
  {
      "cmd": ["rspec.bat", "-I ${file_path}", "$file"]
  }
}

Just a matter of changing "cmd" to run rvm-auto-ruby -S bundle exec rspec instead of just rspec. That will use the ruby from RVM to run bundle exec rspec.

Sublime Package: RubyTest

I’m assuming that you already used Package Control to install RubyTest so that you can use Cmd-Shift-R / Cmd-Shift-T to execute rspec test.

Open ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/RubyTest/RubyTest.sublime-settings and edit it to look like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "env":{
    "PATH":"${HOME}/.rvm/bin:${PATH}"
  },
  "erb_verify_command": "erb -xT - {file_name} | ruby -c",
  "ruby_verify_command": "ruby -c {file_name}",

  "run_ruby_unit_command": "ruby -Itest {relative_path}",
  "run_single_ruby_unit_command": "ruby -Itest {relative_path} -n '{test_name}'",

  "run_cucumber_command": "rvm-auto-ruby -S bundle exec cucumber {relative_path}",
  "run_single_cucumber_command": "rvm-auto-ruby -S bundle exec cucumber {relative_path} -l{line_number}",

  "run_rspec_command": "rvm-auto-ruby -S bundle exec rspec {relative_path}",
  "run_single_rspec_command": "rvm-auto-ruby -S bundle exec rspec {relative_path} -l{line_number}",

  "ruby_unit_folder": "test",
  "ruby_cucumber_folder": "features",
  "ruby_rspec_folder": "spec",

  "ruby_use_scratch" : false,
  "save_on_run": false,
  "ignored_directories": [".git", "vendor", "tmp"],

  "hide_panel": false,

  "before_callback": "",
  "after_callback": ""
}

Here I’ve only edited the "run_rspec_command" but you can use the same philosophy for the rest of the commands (run_ruby_unit_command, etc) if you plan to use them.

The idea is that instead of running rspec {relative_path} you run rvm-auto-ruby -S bundle exec rspec {relative_path}. the rvm-auto-ruby part loads the RVM and the bundle exec part makes sure that you use bundler to load your gems (including maybe a specific version of RSpec itself, if it’s included in the Gemfile).

GDB Posix_spawn Failed on Mac OS X Mountain Lion

If you can’t debug with ddd or gdb on Mac OS X Mountain Lion due to posix_spawn failed error then just run sudo gdb or sudo ddd instead.

The complete error message is

(gdb) run
Starting program: /Users/ecerulm/projects/luaqueue/test 
warning: posix_spawn failed, trying execvp, error: 2
Cannot exec /home/ecerulm/local/bin/zsh -c  exec /usr/bin/arch -arch x86_64 /Users/ecerulm/projects/luaqueue/test .

and after running it as sudo gdb the error is gone

First Steps in LUA-C++ Integration

EDIT: Part 2

Long time without posting, busy at work, family, etc.

Today I decided to write a bit on Lua.

Lua is a scripting language with an emphasis on being easily embeddable. Lua is used as the scripting language in Photoshop CS, and World of Warcraft, for example. So if you are looking into adding scriptability to your C or C++ applications Lua is quite suited for the task.

In order to learn Lua (both the language itself and how to embed it into your app) I recommend you Programming in Lua by one of the Lua authors.

You can find tons of tutorials on how to get started with Lua. So I will focus here on how to integrate with C++. Most of the sources I’ve found about Lua - C++ integrations take the approach of frameworks to automatically wrap your objects/classes to be usable from within Lua. I find this approach confusing, I think it’s better to learn how to do it manually, and that’s what I will do here.

Step 0. Compile Lua itself

Download Lua 5.2.1 and compile it. Usually it enough with make macosx or make linux. That will generate liblua.a, the library that we will link to.

Step 1. Create a simple host app

We need a simple host app. Our host app will simply setup Lua and run a script from it. This script will have access to a std::queue from the host app. This will illustrate how you can share objects with the Lua part. Later we will take a more complex example.

Let’s start with the basic skeleton of a lua environment with some communication with its host:

The Makefile

(Makefile) download
1
2
3
4
LUAHOME=$(HOME)/tmp/lua-5.2.1/src
all: sampleluahost
sampleluahost: sampleluahost.cpp
  g++ -g sampleluahost.cpp -llua -L$(LUAHOME) -I$(LUAHOME) -o sampleluahost

It uses LUAHOME that should point to the directory containing both liblua.a and the lua*.h files.

The samplehost application

(sampleluahost.cpp) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <lua.hpp>


extern "C" {
  static int l_cppfunction(lua_State *L) {
    double arg = luaL_checknumber(L,1);
    lua_pushnumber(L, arg * 0.5);
    return 1;
  }
}

using namespace std;
int main()
{
  cout << "** Test Lua embedding" << endl;
  cout << "** Init Lua" << endl;
  lua_State *L;
  L = luaL_newstate();
  cout << "** Load the (optional) standard libraries, to have the print function" << endl;
  luaL_openlibs(L);
  cout << "** Load chunk. without executing it" << endl;
  if (luaL_loadfile(L, "luascript.lua")) {
    cerr << "Something went wrong loading the chunk (syntax error?)" << endl;
    cerr << lua_tostring(L, -1) << endl;
    lua_pop(L,1);
  }

  cout << "** Make a insert a global var into Lua from C++" << endl;
  lua_pushnumber(L, 1.1);
  lua_setglobal(L, "cppvar");

  cout << "** Execute the Lua chunk" << endl;
  if (lua_pcall(L,0, LUA_MULTRET, 0)) {
    cerr << "Something went wrong during execution" << endl;
    cerr << lua_tostring(L, -1) << endl;
    lua_pop(L,1);
  }

  cout << "** Read a global var from Lua into C++" << endl;
  lua_getglobal(L, "luavar");
  double luavar = lua_tonumber(L,-1);
  lua_pop(L,1);
  cout << "C++ can read the value set from Lua luavar = " << luavar << endl;

  cout << "** Execute a Lua function from C++" << endl;
  lua_getglobal(L, "myluafunction");
  lua_pushnumber(L, 5);
  lua_pcall(L, 1, 1, 0);
  cout << "The return value of the function was " << lua_tostring(L, -1) << endl;
  lua_pop(L,1);

  cout << "** Execute a C++ function from Lua" << endl;
  cout << "**** First register the function in Lua" << endl;
  lua_pushcfunction(L,l_cppfunction);
  lua_setglobal(L, "cppfunction");

  cout << "**** Call a Lua function that uses the C++ function" << endl;
  lua_getglobal(L, "myfunction");
  lua_pushnumber(L, 5);
  lua_pcall(L, 1, 1, 0);
  cout << "The return value of the function was " << lua_tonumber(L, -1) << endl;
  lua_pop(L,1);

  cout << "** Release the Lua enviroment" << endl;
  lua_close(L);
}
(luascript.lua) download
1
2
3
4
5
6
7
8
9
10
11
print("Hello from Lua")
print("Lua code is capable of reading the value set from C++", cppvar)
luavar = cppvar * 3

function myluafunction(times)
  return string.rep("(-)", times)
end

function myfunction(arg)
  return cppfunction(arg)
end

The code explained step by step

Initialization

lua_State *L;
L = luaL_newstate();
luaL_openlibs(L);
if (luaL_loadfile(L, "luascript.lua")) {
  cerr << "Something went wrong loading the chunk (syntax error?)" << endl;
  cerr << lua_tostring(L, -1) << endl;
  lua_pop(L,1);
}

That creates a lua_State loads the standard libs in it and also loads the code in luascript.lua.

Adding variables from C++ into Lua

lua_pushnumber(L, 1.1);
lua_setglobal(L, "cppvar");
if (lua_pcall(L,0, LUA_MULTRET, 0)) {
  cerr << "Something went wrong during execution" << endl;
  cerr << lua_tostring(L, -1) << endl;
  lua_pop(L,1);
}

Then it sets a global variable in Lua from C++ code using lua_setglobal. If you don’t know what are the lua_pushxxxx and the Lua stack, etc. I recoment that you take a look at the Lua Reference Manual and Programming in Lua. More or less Lua and the C++ communicate through the stack that lives in lua_State and there is bunch of function to manipulate that stack. So in order to set a global in Lua from C++ you must push the value into the stack and call lua_setglobal that will pop the value in the stack and assign it to the identifier provided inside the Lua environment.

After setting the global cppvar it executes the loaded chunk of code (that is in the stack) with lua_pcall. The Lua code is able to read and print the value of cppvar. The lua code will also set a new global luavar that we will access from C++.

Reading a Lua variable from C++

lua_getglobal(L, "luavar");
double luavar = lua_tonumber(L,-1);
lua_pop(L,1);
cout << "C++ can read the value set from Lua luavar = " << luavar << endl;

To get luavar from C++, we must first use lua_getglobal that will put the value associated with the identifier into the top of the stack and the lua_tonumber will transform whatever it’s at the top of the stack into a double (well a luaNumber) and then we can use that double in our C++ code to print it.

Calling a Lua function from C++

cout << "** Execute a Lua function from C++" << endl;
lua_getglobal(L, "myluafunction");
lua_pushnumber(L, 5);
lua_pcall(L, 1, 1, 0);
cout << "The return value of the function was " << lua_tostring(L, -1) << endl;
lua_pop(L,1);

The example won’t be complete without function calling so that’s the next step. Calling a Lua function from C++ it’s quite easy. Function in Lua are first class values, so that means that it’s just a like reading a any other value. lua_getglobal will get the value and put it on the stack and then we push the function arguments into the stack and use lua_pcall to call the function (that is the stack). The returned value from the function will be pushed in the stack and that’s were the C++ code will get it, lua_tostring and then it will remove from the stack with lua_pop.

Calling a C++ function from Lua

lua_pushcfunction(L,l_cppfunction);
lua_setglobal(L, "cppfunction");

lua_getglobal(L, "myfunction");
lua_pushnumber(L, 5);
lua_pcall(L, 1, 1, 0);
cout << "The return value of the function was " << lua_tonumber(L, -1) << endl;
lua_pop(L,1);

The other way around it’s more complex. You can’t just call any function from Lua. It has to has a special signature lua_CFunction, that is, typedef int (*lua_CFunction) (lua_State *L) a function that returns an int and takes a lua_State. This special funciton will communicate with Lua via the lua stack that resides in the lua_State parameter. The return value of the function tell lua how many value the function has pushed into the stack as result values for the function call.

So to make the function accesible from Lua, you create push the function into the stack with lua_pushcfunction and bind it to an identifier in lua with lua_setglobal. Then lua code will be able to invoke this function like any other function. In the example I call the myfunction (which is lua code) and myfunction in turn invokes cppfunction which is “bound” to C++ l_cppfunction. Ah, I almost forgot. l_cppfunction is declared as extern "C" telling the compiler to provide C linkage for this function so it can be called from a C library like Lua is.

Free Lua resources

lua_close(L);

lua_close will free all resources held by the lua_State L.

Wrap up

I will leave the part on how to wrap C++ class objects in Lua for a later post because I don’t want to make this post too long. Hopefully I’ll post it tomorrow.

Sublime Text 2 RVM and RSpec

EDIT This post is obsolete. It has been superseeded by this newer post

OBSOLETE
OBSOLETE
OBSOLETE

I found out about Sublime Text 2 from the Ruby Rogues podcast, and I’m loving it. Although is has been a little problematic to set it up to honor my .rvmrc files and to run RSpec files from it.

First to get it to honor the .rvmrc project file you need to follow the instructions at this post . To make it easier for you I copied the instructions here: you must create a $HOME/bin/sublime_rvm.rb with the following content:

and make it executable with chmod +x ~/bin/sublime_rvm.rb then update your ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/Ruby/Ruby.sublime-build to look like this:

After this you should be able to run a ruby file from Sublime Text 2 using Cmd-B and it will use whatever ruby version is specified in the .rvmrc for that project.

Having done that I created a ~/bin/sublime_rpec.rb file with the following content

and then I used Package Control to install RubyTest and modified ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/RubyTest/RubyTest.sublime-settings like this:

Of course you should point to your sublime_rspec.rb path which will differ from mine. And now when I press Cmd-Shift-R, Sublime Text will run the file with RSpec. Well in my case I prefer to run the RSpec test with the the bundled version of RSpec for the project, that’s why I use bundle exec rspec #{file} in the script. If you want to use the RSpec gem installed in your rvm gemset remove the bundle exec part.

Running a Custom TestRunner From Rake

I was surprised when I searched in Google for ways of running a custom TestRunner in a Rake::TestTask and I couldn’t find anything directly.

So after figuring out myself how it’s done I decided to share it here:

Let’s say that you have the following TestRunner (learn how to write your custom TestRunner)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Usage:
#   ruby -rstat_runner [test] --runner=stat
# http://endofline.wordpress.com/2008/02/11/a-custom-testrunner-to-scratch-an-itch/require 'test/unit'
require 'test/unit/ui/console/testrunner'
class StatRunner < Test::Unit::UI::Console::TestRunner
  def finished(elapsed_time)
    nl
    output("="*72)
    output("|"+"Finished in #{elapsed_time} seconds.".center(70)+"|")
    output("="*72)
    nl
    output(@result)
  end
end

Test::Unit::AutoRunner::RUNNERS[:stat] = proc do |r|
  StatRunner
end

This new StatRunner is very simple and the only customization is that it prints the result line wrapped in a box.

Now imagine that this StatRunner is defined in the test/stat_runner.rb file. The rake task in the rakefile would look like:

1
2
3
4
5
6
7
8
9
# http://rake.rubyforge.org/classes/Rake/TestTask.html
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
  test.libs << 'lib' << 'test'  # test dir is in, so we can do -rstat_runner
  test.ruby_opts=['-rstat_runner'] # require stat_runner.rb in spawned ruby process  
  test.pattern = 'test/**/test_*.rb'
  test.verbose = true
  test.options="--runner=stat" #force to use the new runner called stat (has to be in RUNNERS)
end

That’s it. Now if you run your rakefile you’ll get

  Started

  ========================================================================
  |                    Finished in 0.000103 seconds.                     |
  ========================================================================

  1 tests, 1 assertions, 0 failures, 0 errors

Compiling OpenChronos in Windows

I got the EZ430 Chronos some days ago and after play around a little with the Code Composer Studio v4 that comes with it (the free code size limited version) I got the TI firmware compiled and uploaded to the watch. Then I realized that what I compiled it was a stripped down version of the firmware called Limited as the code-size-limited CCSv4 cannot be used to compiled the Unrestricted firmware.

So now to get a decent firmware in the EZ430 I need either the full CCSv4 or another toolchain for the MSP430 MCUs with specific support for CC430F6137 which is the processor present in the eZ430-Chronos . CCSv4 is quite expensive: ~500USD so I started looking for other toolchains.

I tried mspgcc but it didn’t really work for me. I was getting compilation errors, and I didn’t feel like investigating those. Then I turn into OpenChronos which seems to be the TI firmware but just modified enough to be able to compile using the mspgcc4 toolchain so I started exploring that path.

I couldn’t get the Win32 port of mspgcc4 to work properly (seems to me that the Win32 has been updated in a while). So at the end I had to use it from Cygwin . These are the steps that I took:

  1. Install wget, patch, gcc 4 , make, python and perl in Cygwin
  2. Download the source distribution of mspgcc4
  3. Unpack it inside a Cygwin bash shell
    1
    2
    
    cd tmp
    tar xvjf /cygdrive/c/Users/xxxx/Downloads/mspgcc4-20110130.tar.bz2

  4. Build mspgcc
    1
    2
    
    cd mspgcc4-20110130
    ./buildgcc.pl

    Select gcc-4.4.5, no gdb, no insight, ti_20110130, and the rest of the defaults.
  5. After a long compile mspgcc4 should be installed in /opt/msp430-gcc-4.4.5/
  6. Add export PATH=$PATH:/opt/msp430-gcc-4.4.5/bin to ~/.bashrc
  7. Download OpenChronos
    1
    2
    3
    4
    5
    6
    7
    8
    
    cd ~
     git clone git://github.com/poelzi/OpenChronos.git
     Cloning into OpenChronos...
     remote: Counting objects: 1485, done.
     remote: Compressing objects: 100% (550/550), done.
     remote: Total 1485 (delta 972), reused 1364 (delta 877)Receiving objects  93%
     Receiving objects: 100% (1485/1485), 666.11 KiB | 411 KiB/s, done.
     Resolving deltas: 100% (972/972), done.
  8. Configure the build
    cd OpenChronos
    make config
  9. Select the proper frequency (868Mhz if you are in Europe) and save
  10. Run make
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    make
      Assembling even_in_range in one step for MSP430...
      msp430-gcc -D_GNU_ASSEMBLER_ -x assembler-with-cpp -c even_in_range.s -o even_in_range.o
      Compiling main for MSP430...
      msp430-gcc -mmcu=cc430x6137 -Os -Wall -fomit-frame-pointer -fno-force-addr -finline-limit=1 -fno-schedule-insns  -Wl,-Map=output.map -o build/eZChronos.elf logi
      ... 
      ...
      ... 
      ronos.o gcc/intrinsics.o  even_in_range.o
      Convert to TI Hex file
      python tools/memory.py -i build/eZChronos.elf -o build/eZChronos.txt
      ELF section .text at 0x8000 32224 bytes
      ELF section .data at 0xfde0 150 bytes
      ELF section .vectors at 0xff80 128 bytes
      convert to TI Hex
  11. Upload the new compiled firmware build/eZChronos.txt using the Wireless update feature of Chronos Control Center (you have to have the USB access point connected, of course)
    1. Select the firmware file c:/cygwin/home/xxxxxx/OpenCronos/build/eZChronos.txt
    2. Click on Update Chronos Watch button
    3. In the watch, navigate to rFbSL (using the # button) and start it (by holding #). If everything goes at it should the download will start and you will see the percentage of firmware tranferred so far in the watch screen (also in Chronos Control Center).

If you think that there is something missing or not clear, leave a comment.

Training a Specific Opening With Rybka Aquarium

I recently bought the Rybka 4 Aquarium + Chess Assistant 11 combo from ChessOK and I was trying to figure out how to practice openings with it.

DISCLAIMER: If you know of any other better way to do this or you think something is not clear, please leave a comment!

In Chapter 11:Trees of the Aquarium manual they mention how “discarded moves” trees can be used for making Aquarium play certain openings over others:

[…] After you have created an opening book you can use the discarded moves tree to create a “mask” for it to play or not play certain moves or openings. You can have one opening book and as many “discarded moves” trees as you like. This means that if you store your whole opening repertoire in a single opening book you can, for instance, define the following “discarded moves” trees:
1) One that only plays the gambit openings in your opening book
2) One that never plays the Sicilian
3) One that only plays queen pawn openings as white.
4) One that whenever possible plays the Sicilian Dragon as black.

But it doesn’t exactly explain how (Shame on them! :). So I tried to figure out myself how to do it with the help of the rybkaforums.net (Thanks to Felix Kling, ppipper and buffos). After reading several times the manual, this , this and this I think I understand how to do it. Let me explain it.

First, some background…

Tree configurations

To understand better tree configurations_ read the ChessCafe: Introduction to Tree Configurations and buffos i-book about tree configurations. I will try to describe tree configuration briefly here but it’s worth reading those two documents.

A tree configuration is a set of “regular” trees containing precomputed informations about the board positions plus a maintree and discarded tree. The “regular” trees are positional trees, graphs where the nodes are board positions and edges are the moves that connect one position to another. Attached to each board position there is some information, for example an engine evaluation for the position, success ratio statistics, textual annotations, etc. A tree configuration “merges” at runtime those trees and computes some other attributes (columns) derived from the info in those trees. These trees are considered read-only from Aquarium point of view.

Then there are two special “trees” in each tree configuration. The maintree and the discarded tree. These trees you can modify from the Aquarium GUI. When you mark a move as good/interesting/bad etc in the tree that information is stored in the maintree. If you mark a move as discarded or set the playing probability of a move by hand that information will be stored in the discarded tree.

So by creating different tree configurations with different maintrees and discarded trees you can use as opening books you can make rybka to play different opening moves. We’ll see how to do it right now…

Examples: One that only plays the gambit openings in your opening book

Let’s begin by going to the tree configurations dialog (Sandbox mode ⇒ Tree ⇒ Options) and create a new tree configuration (see chesscafe article for details) from the NarrowBook tree configuration.

and name it “gambits” for example. Then change the “Main tree path” to gambits_maintree and “Discarded tree path” to gambits_discarded. This will create an empty maintree and empty discarded tree, new trees that are not shared by any other tree configuration, this is important because you don’t want the changes in gambit tree configuration affect any other tree configuration.

Now we can proceed to set the Play% (playing probability) of the moves from the Aquarium GUI.

You can influence the Play% of the moves in two ways (that I know of):

First you can just set the playing probability by clicking on “Enter percents…” (or using the faster keyboard shortcut “+”). This is what I recommend

Or you can mark the move as good/interesting/dubious/bad/discarded. If you mark it as good you will prioritize the move, if you mark it as bad or discarded it won’t be played. For details about how the prioritizations actually works take a look at the following i-book (pay special attention to the Bonus system chapter).

Obviously the first gives you fine tuned control over the playing probability and that’s the method that I’ll be using here.

So let’s make this tree configuration to play only 1.e4 or 1.d4 when playing as white by using “+” key to set both to 50%.

So far, so good. By using this opening book “gambits” rybka will always play e4 or d4 as first move. Now we are going to force to always play the King’s gambit if black plays 1...e5.

On the tree select 1.e4 and press right arrow (→). Then it will present the black alternatives to 1.e4 among those 1...e6 , 1...e5, etc. Locate and select 1...e5 (using the up ↑ and down ↓ arrows to navigate between options) and right arrow → to go into move 1...e5, we don’t need to set the play probability for 1...e5 because we are not interested on rybka playing 1...e5 (we want to practice these openings with the human player playing black). Then go down until you see 2.f4 and press + to set 100% play probability. Using the keyboard to modify the tree is way faster than using the mouse so learn the keyboar shortcuts.

Let’s also program this opening book to play the Queen’s gambit whenever is possible.

Navigate in the tree window from 1.d41...d5 → and select 2.c4 and set playing probability to 100% with the “+” key.

Now you can go to Play mode and let Rybka play the white (make sure you select “gambits” opening book) and you will see that white always plays the King’s gambit or the Queen’s gambit.

Example: One that whenever possible plays the Sicilian Dragon as black

Now let’s create a new tree configuration that plays Sicilian Dragon whenever is possible. This time we will use the Rybka Opening book as base and keep the good move/bad move coloring did by Jiri Dufek

Ok, first go to Sandbox mode ⇒ Tree ⇒ Options and select Rybka4_book from the list of configurations. Click on New ⇒ Copy current configuration (Rybka4_book) ⇒ Next and name it “sicilian_dragon_black”.

Leave the Main tree path as “Rybka4book\rybka4_Jiri_Dufek” and replace Discarded tree path with “discarded_sicilian_dragon_black”. You will end up with the following:

So now let’s force Rybka to play Sicilian Dragon . Select 1.e4 and right arrow →, select 1...c5 press “+” and set 100%. Press right arrow → to go the next move (white), select 2.Nf3 right arrow → and select 2...d6 and set it to 100%, do the same for 3...cxd4, 4...Nf6 and 5...g6. And that’s it:

Links

From Textdrive to Joyent Shared Accelerator

After delaying it for long, long time I finally moved from Textdrive to Joyent Shared Accelerator. The improvement has been considerable. The response time has halved (blue line), and after a few days I switched to jekyll for the blog platform and the improvements has been event bigger!

Fixing Disqus

I was checking the Disqus threads for my site in the Disqus web page and I noticed that there was something wrong. Some threads had the wrong url, pointing to http://localhost:4000 and some had the wrong title (instead of the title the url was showing). I came to the conclusion that this was due to the fact that I’ve been using disqus_developer=1 to test locally after migrating to Disqus and the threads that I visited for the first time locally got the local url (localhost) and the because disqus couldn’t get the title from that url (since it was a local url) it assigned a title based on the (local) url.

So I decided to fix it using the Disqus API and I wrote the following script

that uses a slightly modified version of the disqus ruby. I had to modify the disqus ruby because the original version can only iterate over the first 25 threads.