Process image stream in Lua by importing image pointer from C++ - c++

I am working on a deep learning task in Lua and I need to import an image stream into Lua from C++. The C++ script is reading data from a shared memory and I have the pointer to the images in C++. I would like to get this pointer in Lua and give the image stream to my Neural Network.
Since Lua does not use pointers and as far as my research the way to go is to wrap this pointer into userdata and write accessor methods. As explained in this User Data With Pointer Example.
My problem is that I need to feed the neural network with raw pixel data and so far the material available online suggests that processing on data should be done in C++ and there is no way to get that object in Lua directly.
What should be the correct approach here? How can I get object values in Lua from pointer in C++?

Well, you have to make the data accessible to Lua in some way.
I can think of four general approaches:
converting the data
writing C(++) code that traverses the data to create a Lua data
structure made of tables & primitive values (booleans, numbers,
strings)
converting the data to an interchange format (JSON, CBOR, … or in the
case of image data:
PNM / PAM) for which
you have code on both sides or can trivially write it
(I won't say any more on these options here.)
passing it in as userdata and writing accessor functions, so you can write the conversion code in Lua instead of C(++)
(only for pointer-free data, and images usually are that) passing the raw data area to Lua as a string
(LuaJIT only) using ffi.cdef to declare C structs that match the in-memory format for free access & conversion (int, float, doesn't matter – can also work with pointers)
(2) is basically just (1a) with most of the code shifted to the Lua side.
(3) is the same with free accessor code (string.byte( data, i[, j]) and a bunch of others, newly added in 5.3: string.unpack(fmt, data[, startpos] ) ).
Before deciding on one of those approaches, look at what format the other side wants.
Maybe your data is already in that format, in which case you would only have to route through the pointer in some way. (Maybe there's a function accepting a Lua table, but maybe there's also one that accepts a string or pointer to raw image data.) If this applies, use (light) userdata or strings for communication. (This will probably be the fastest, and if this way of passing the data doesn't exist yet consider asking upstream whether they can add it.)
Failing that, you'll have to actually touch the data. The string version is potentially the easiest, but also likely to be the slowest. (If the data is one contiguous block of bytes, you can simply lua_pushlstring( L, ptr, len_in_bytes ) to get everything into Lua, but that creates a copy of the "string" internal to the Lua state which might be relatively slow.) After that, you can use the standard string handling functionality of Lua.
If you're using LuaJIT, it's probably a very good idea to use the ffi library. A very brief outline of what you may need (using a linked list as example):
ffi = require "ffi"
-- sample structure, yours will differ
ffi.cdef [[
typedef struct Node_s { struct Node_s *next; int value; } Node;
]]
-- in your case you will get a pointer from C, which you can then
-- ffi.cast( "Node*", ptr )
-- after that, you can access the fields (ptr.next, ptr.value etc.)
-- we'll just use some dummy sample data here:
do
local p = ffi.new( "Node" )
local q = ffi.new( "Node" )
p.next = q
p.value, p.next.value = 23, 42
ptr = tonumber( tostring( p ):match( ": (0x%x*)" ) )
end
data = ffi.cast( "Node*", ptr )
print( "first value:", data.value )
--> first value: 23
print( "second value:", data.next.value )
--> second value: 42
print( "third value:", data.next.next.value )
--> Segmentation fault [so be just as careful as you're in C(++)!]
Lastly, if you're on vanilla Lua, you may want to use (full) userdata and manually written accessors to avoid the speed loss from data copying. (The full userdata is required so you can set a metatable to get the accessors, but it can simply be a pointer to your externally allocated data.) The book "Programming in Lua" has good information on that (first edition is online, direct link to the relevant chapter.)

Related

deserialize data on the fly from stream or file

It is more or less quite easy to serialize and deserialze data structures with common libraries like boost::serialize.
But there is an also common case where I simply do something like ( pseudo code ):
// receiver
NetworkInputStreamSerialzer stream;
while (1) // read new data objects from stream
{
stream & data;
}
As I expect the data package must already be received complete from the network socket. If only a part of the object can be read the deserialization will fail. Especially with large data sets TCP will fragment the data.
Is there a generic way to deal with this problem? I have not found any hints to this problem in the docs from boost::serialize.
As this problem is generic to any kind of streamed data, not only for TCP based streaming but also for files where one prog sends and another receives the data, there must be a general solution but I could not find anything about.
My question is not specialized to boost. I use it only as an example.
EDIT:
Maybe some more explanation to my wording of "fragmentation":
Any kind of data, independent of the size it produces in serialized format, can be fragmented in several packages while transferred via TCP or by writing it to any kind of file. There is no kind of "atomic" write and read operation which is supported from the OS neither the serialization libraries I know.
So if reading an int from a human readable format like XML or JSON I can get the problem that I read a "11" instead of "112" if the "2" is not in the stream or file in the moment I read from it. So writing the length of the following content in a human readable format is also not a solution, because the size information itself can be corrupt while the read occurs in the moment the content string is not complete in this moment.
[Note: I get a sense from your Q, that you want a better alternative for boost::serialization for your specific case. If this doesn't answer your Q, then let me know, I shall delete it.]
Recommending to use Google Protocol Buffers from my own practical experience. Below are few advantages:
It can be used on wire (TCP etc.)
Simple grammar to write the .proto file for composing your own
messages
Cross platform & available with multiple languages
Very efficient compared to JSON & XML
Generates header & source files for handy getter, setter, serialize,
deserialize & debugging purpose
Easy to serialize & deserialize -- store to & retrieve from file
The last point is bit tricky. While storing in a file, you may have to insert the length of the message first and while retrieving, you may have to first read that length & then use read() method to read the exact number of bytes.
Above same trick you may want to use while passing on TCP. In first couple of bytes, the length can be passed. Once the length is determined, you can always collect the remaining fragmented message.

What's the OCaml naming convention for "constructors"?

An OCaml module usually contains at least one abstract type whose idiomatic name is t. Also, there's usually a function that constructs a value of that type.
What is the usual / idiomatic name for this?
The StdLib is not consistent here. For example:
There's Array.make and a deprecated function Array.create. So that function should be named make?
On the other hand, there's Buffer.create but not Buffer.make. So that function should be named create?
Some people find this way of module design makes OCaml programming easier, but this is not a mandatory OCaml programming style, and I do not think there is no official name for it. I personally call it "1-data-type-per-1-module" style. (I wrote a blog post about this but it is in Japanese. I hope some autotranslator gives some useful information to you ...)
Defining a module dedicated to one data type and fix the name of the type t has some values:
Nice namespacing
Module names explain about what its type and values are, therefore you do not need to repeat type names inside: Buffer.add_string instead of add_string_to_buffer, and Buffer.create instead of create_buffer. You can also avoid typing the same module names with local module open:
let f () =
let open Buffer in
let b = create 10 in (* instead of Buffer.create *)
add_string b "hello"; (* instead of Buffer.add_string *)
contents b (* instead of Buffer.contents *)
Easy ML functor application
If an ML functor takes an argument module with a data type, we have a convention that the type should be called t. Modules with data type t are easily applied to these functors without renaming of the type.
For Array.create and Array.make, I think this is to follow the distinction of String.create and String.make.
String.create is to create a string with uninitialized contents. The created string contains random bytes.
String.make is to create a string filled with the given char.
We had Array.create for long, to create an array whose contents are filled with the given value. This behavior corresponds with String.make rather than String.create. That's why it is now renamed to Array.make, and Array.create is obsolete.
We cannot have Array.create in OCaml with the same behaviour of String.create. Unlike strings, arrays cannot be created without initialization, since random bytes may not represent a valid OCaml value for the content in general, which leads to a program crash.
Following this, personally I use X.create for a function to create an X.t which does not require an initial value to fill it. I use X.make if it needs something to fill.
I had the same question when I picked up the language a long time ago. I never use make and I think few people do.
Nowadays I use create for heavy, often imperative or stateful values, e.g. a Unicode text segmenter. And I use v for, functional, lighter values in DSL/combinator based settings, e.g. the various constructors in Gg, for example for 2D vectors, or colors.
As camlspotter mentions in his answer the standard library distinguishes make and create for values that need an initial value to fill in. I think it's better to be regular here and always use create regardless. If your values support an optional initial fill value, add an optional argument to create rather than multiply the API entry points.

How to print elements from tcl_obj in gdb?

I am debugging a c++-tcl interface application and I need to see the elements of Tcl_Obj objv.
I tried doing print *(objv[1]) and so on but it doesnt seem helping.
Is there any way to see Tcl_Obj elements in gdb?
It's not particularly easy to understand a Tcl_Obj * from GDB as the data structure uses polymorphic pointers with shrouded types. (Yeah, this is tricky C magic.) However, there are definitely some things you can try. (I'll pretend that the pointer is called objPtr below, and that it is of type Tcl_Obj *.)
Firstly, check out what the objPtr->typePtr points to, if anything. A NULL objPtr->typePtr means that the object just has something in the objPtr->bytes field, which is a UTF-8 string containing objPtr->length bytes with a \0 at objPtr->bytes[objPtr->length]. A Tcl_Obj * should never have both its objPtr->bytes and objPtr->typePtr being NULL at the same time.
If the objPtr->typePtr is not NULL, it points to a static constant structure that defines the basic polymorphic type operations on the Tcl_Obj * (think of it as being like a vtable). Of initial interest to you is going to be the name field though; that's a human-readable const char * string, and it will probably help you a lot. The other things in that structure include a definition of how to duplicate the object and how to serialize the object. (The objPtr->bytes field really holds the serialization.)
The objPtr->typePtr defines the interpretation of the objPtr->internalRep, which is a C union that is big enough to hold two generic pointers (and a few other things besides, like a long and double; you'll also see a Tcl_WideInt, which is probably a long long but that depends on the compiler). How this happens is up to the implementation of the type so it's difficult to be all-encompassing here, but it's basically the case that small integers have the objPtr->internalRep.longValue field as meaningful, floating point numbers have the objPtr->internalRep.doubleValue as meaningful, and more complex types hang a structure off the side.
With a list, the structure actually hangs off the objPtr->internalRep.twoPtrValue.ptr1 and is really a struct List (which is declared in tclInt.h and is not part of Tcl's public API). The struct List in turn has a variable-length array in it, the elements field; don't modify inside there or you'll break things. Dictionaries are similar, but use a struct Dict instead (which contains a variation on the theme of hash tables) and which is declared just inside tclDictObj.c; even the rest of Tcl's implementation can't see how they work internally. That's deliberate.
If you want to debug into a Tcl_Obj *, you'll have to proceed carefully, look at the typePtr, apply relevant casts where necessary, and make sure you're using a debug build of Tcl with all the symbol and type information preserved.
There's nothing about this that makes debugging a whole array of values particularly easy. The simplest approach is to print the string view of the object, like this:
print Tcl_GetString(objv[1])
Be aware that this does potentially trigger the serialization of the object (including memory allocation) so it's definitely not perfect. It is, however, really easy to do. (Tcl_GetString generates the serialization if necessary — storing it in the objPtr->bytes field of course — and returns a pointer to it. This means that the value returned is definitely UTF-8. Well, Tcl's internal variation on UTF-8 that's slightly denormalized in a couple of places that probably don't matter to you right now.)
Note that you can read some of this information from scripts in Tcl 8.6 (the current recommended release) with the ::tcl::unsupported::representation command. As you can guess from the name, it's not supported (because it violates a good number of Tcl's basic semantic model rules) but it can help with debugging before you break out the big guns of attaching gdb.

Named parameter string formatting in C++

I'm wondering if there is a library like Boost Format, but which supports named parameters rather than positional ones. This is a common idiom in e.g. Python, where you have a context to format strings with that may or may not use all available arguments, e.g.
mouse_state = {}
mouse_state['button'] = 0
mouse_state['x'] = 50
mouse_state['y'] = 30
#...
"You clicked %(button)s at %(x)d,%(y)d." % mouse_state
"Targeting %(x)d, %(y)d." % mouse_state
Are there any libraries that offer the functionality of those last two lines? I would expect it to offer a API something like:
PrintFMap(string format, map<string, string> args);
In Googling I have found many libraries offering variations of positional parameters, but none that support named ones. Ideally the library has few dependencies so I can drop it easily into my code. C++ won't be quite as idiomatic for collecting named arguments, but probably someone out there has thought more about it than me.
Performance is important, in particular I'd like to keep memory allocations down (always tricky in C++), since this may be run on devices without virtual memory. But having even a slow one to start from will probably be faster than writing it from scratch myself.
The fmt library supports named arguments:
print("You clicked {button} at {x},{y}.",
arg("button", "b1"), arg("x", 50), arg("y", 30));
And as a syntactic sugar you can even (ab)use user-defined literals to pass arguments:
print("You clicked {button} at {x},{y}.",
"button"_a="b1", "x"_a=50, "y"_a=30);
For brevity the namespace fmt is omitted in the above examples.
Disclaimer: I'm the author of this library.
I've always been critic with C++ I/O (especially formatting) because in my opinion is a step backward in respect to C. Formats needs to be dynamic, and makes perfect sense for example to load them from an external resource as a file or a parameter.
I've never tried before however to actually implement an alternative and your question made me making an attempt investing some weekend hours on this idea.
Sure the problem was more complex than I thought (for example just the integer formatting routine is 200+ lines), but I think that this approach (dynamic format strings) is more usable.
You can download my experiment from this link (it's just a .h file) and a test program from this link (test is probably not the correct term, I used it just to see if I was able to compile).
The following is an example
#include "format.h"
#include <iostream>
using format::FormatString;
using format::FormatDict;
int main()
{
std::cout << FormatString("The answer is %{x}") % FormatDict()("x", 42);
return 0;
}
It is different from boost.format approach because uses named parameters and because
the format string and format dictionary are meant to be built separately (and for
example passed around). Also I think that formatting options should be part of the
string (like printf) and not in the code.
FormatDict uses a trick for keeping the syntax reasonable:
FormatDict fd;
fd("x", 12)
("y", 3.141592654)
("z", "A string");
FormatString is instead just parsed from a const std::string& (I decided to preparse format strings but a slower but probably acceptable approach would be just passing the string and reparsing it each time).
The formatting can be extended for user defined types by specializing a conversion function template; for example
struct P2d
{
int x, y;
P2d(int x, int y)
: x(x), y(y)
{
}
};
namespace format {
template<>
std::string toString<P2d>(const P2d& p, const std::string& parms)
{
return FormatString("P2d(%{x}; %{y})") % FormatDict()
("x", p.x)
("y", p.y);
}
}
after that a P2d instance can be simply placed in a formatting dictionary.
Also it's possible to pass parameters to a formatting function by placing them between % and {.
For now I only implemented an integer formatting specialization that supports
Fixed size with left/right/center alignment
Custom filling char
Generic base (2-36), lower or uppercase
Digit separator (with both custom char and count)
Overflow char
Sign display
I've also added some shortcuts for common cases, for example
"%08x{hexdata}"
is an hex number with 8 digits padded with '0's.
"%026/2,8:{bindata}"
is a 24-bit binary number (as required by "/2") with digit separator ":" every 8 bits (as required by ",8:").
Note that the code is just an idea, and for example for now I just prevented copies when probably it's reasonable to allow storing both format strings and dictionaries (for dictionaries it's however important to give the ability to avoid copying an object just because it needs to be added to a FormatDict, and while IMO this is possible it's also something that raises non-trivial problems about lifetimes).
UPDATE
I've made a few changes to the initial approach:
Format strings can now be copied
Formatting for custom types is done using template classes instead of functions (this allows partial specialization)
I've added a formatter for sequences (two iterators). Syntax is still crude.
I've created a github project for it, with boost licensing.
The answer appears to be, no, there is not a C++ library that does this, and C++ programmers apparently do not even see the need for one, based on the comments I have received. I will have to write my own yet again.
Well I'll add my own answer as well, not that I know (or have coded) such a library, but to answer to the "keep the memory allocation down" bit.
As always I can envision some kind of speed / memory trade-off.
On the one hand, you can parse "Just In Time":
class Formater:
def __init__(self, format): self._string = format
def compute(self):
for k,v in context:
while self.__contains(k):
left, variable, right = self.__extract(k)
self._string = left + self.__replace(variable, v) + right
This way you don't keep a "parsed" structure at hand, and hopefully most of the time you'll just insert the new data in place (unlike Python, C++ strings are not immutable).
However it's far from being efficient...
On the other hand, you can build a fully constructed tree representing the parsed format. You will have several classes like: Constant, String, Integer, Real, etc... and probably some subclasses / decorators as well for the formatting itself.
I think however than the most efficient approach would be to have some kind of a mix of the two.
explode the format string into a list of Constant, Variable
index the variables in another structure (a hash table with open-addressing would do nicely, or something akin to Loki::AssocVector).
There you are: you're done with only 2 dynamically allocated arrays (basically). If you want to allow a same key to be repeated multiple times, simply use a std::vector<size_t> as a value of the index: good implementations should not allocate any memory dynamically for small sized vectors (VC++ 2010 doesn't for less than 16 bytes worth of data).
When evaluating the context itself, look up the instances. You then parse the formatter "just in time", check it agaisnt the current type of the value with which to replace it, and process the format.
Pros and cons:
- Just In Time: you scan the string again and again
- One Parse: requires a lot of dedicated classes, possibly many allocations, but the format is validated on input. Like Boost it may be reused.
- Mix: more efficient, especially if you don't replace some values (allow some kind of "null" value), but delaying the parsing of the format delays the reporting of errors.
Personally I would go for the One Parse scheme, trying to keep the allocations down using boost::variant and the Strategy Pattern as much I could.
Given that Python it's self is written in C and that formatting is such a commonly used feature, you might be able (ignoring copy write issues) to rip the relevant code from the python interpreter and port it to use STL maps rather than Pythons native dicts.
I've writen a library for this puporse, check it out on GitHub.
Contributions are wellcome.

Example usage where Lua fits much better than C/C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm currently embedding Lua and using it as a glorified intelligent config file. However, I think I'm missing something since people rave about the uses of Lua.
For example, I can easily explain why you might use shell scripting instead of C by showing this example (admittedly , boost regexp is overkill):
#include <dirent.h>
#include <stdio.h>
#include <boost/regex.hpp>
int main(int argc, char * argv[]) {
DIR *d;
struct dirent *dir;
boost::regex re(".*\\.cpp$");
if (argc==2) d = opendir(argv[1]); else d = opendir(".");
if (d) {
while ((dir = readdir(d)) != NULL) {
if (boost::regex_match(dir->d_name, re)) printf("%s\n", dir->d_name);
}
closedir(d);
}
return(0);
and compare it to:
for foo in *.cpp; do echo $foo; done;
Are there any examples that you can give in Lua which can make it 'click' for me?
EDIT: Maybe my problem is that I don't know Lua well enough yet to use it fluently as I'm finding it easier to write C code.
EDIT2:
One example is a toy factorial program in C++ and Lua:
#include <iostream>
int fact (int n){
if (n==0) return 1; else
return (n*fact(n-1));
}
int main (){
int input;
using namespace std;
cout << "Enter a number: " ;
cin >> input;
cout << "factorial: " << fact(input) << endl;
return 0;
}
Lua:
function fact (n)
if n==0 then
return 1
else
return n * (fact(n-1))
end
end
print ("enter a number")
a = io.read("*number")
print ("Factorial: ",fact(a))
Here, the programs look alike, but there's clearly some cruft in the include, namespace and main() declarations you can get rid of. Also remove variable declarations and strong typing.
Now are people saying this is the advantage which adds up over a larger program, or is there more to it? This doesn't stand out in the same way as the bash example.
Using a scripting language such as Lua has many other benefits.
A couple of advantages to Lua vs. C++:
It's often shorter in terms of development time due to the high-level nature, as in your example.
It doesn't require recompilation to change behavior.
Behavior can be changed on non-development machines.
Prototyping is very fast and easy, since you can just tweak logic at runtime.
Scripting languages reduce the effort required to build complex GUIs that otherwise require a lot of framework glue and repetition of code. Several GUI toolkits are available with Lua bindings, including wxWidgets and the IUP toolkit.
In both of those bindings, first class function values and full closures make event callbacks easy to code and easy to use.
A large application using Lua at its core (such as Adobe Photoshop Lightroom) has an outer C/C++ program that hosts the Lua interpreter and provides access to its core features by registering C functions with that interpreter. It typically implements compute-intensive core functions in C functions, but leaves the overall flow, operation, and even the GUI layout to Lua scripts.
I have found in my own projects that it is often the case that the stock standalone Lua interpreter (lua.exe or wlua.exe) is sufficient for the outer application when combined with IUP loaded at run time along with one or two custom DLL-based Lua modules coded in C that implement features that require that level of performance, or features that are implemented via other C-callable libraries.
The important points for my projects have included:
True tail calls allow for a easy expression of finite state machines.
Garbage collected memory management.
Anonymous functions, closures, first class function values.
Hash tables.
Rich enough string library.
Userdata extends the garbage collector to C side allocations.
Metatables allow a rich variety of object oriented and functional techniques.
Small but sufficiently powerful C API.
Good documentation, with open source as a backup.
Good user to user support through the mailing list and wiki.
Powerful modules such as a PEG parser available from the authors and from the community.
One of my favorite examples to cite is a test jig I built for an embedded system that required about 1000 lines of Lua and 1000 lines of C, ran under lua.exe, and used IUP to present a full Windows GUI. The first version was running in about a day. In C++ with MFC, it would have been at least a week's work, and many thousands of lines of code.
I don't know if I make it 'click' for you but I'll try.
One of the advantages of embedding Lua is, that you can not only use it as a configfile but actually offer your C/C++-interfaces to lua and 'script' their usage via the Lua-scripting language.
If you want to change the behaviour/logic of your application, you just have to change the code in the Lua-script without the need to recompile the whole application.
Prominent uses are game logics like AI oder state machines, where a fast roundtrip-time from change to play is essential for developing the game.
Of course, the main logic has then to be present within the Lua-script, not within the C/C++-code, to be effectively used.
Try to implement a Lua table in C/C++, you'll see the strength of Lua right there.
In Lua:
a["index"] = "value"
In C, start by reading about linked list...
C++ STL may help, but it is going to be a lot more verbose than Lua.
Also, Lua makes great glue. It is so easy (IMHO) to interface to C.
Programming just in C can be a very tedious and redundant task, this certainly applies when compared to more abstract, high level languages.
In this sense, you can get started and finish things much more quickly than doing everything directly in C, this is because many things that need to be set up, done and cleaned up explicitly and manually in C, are often implicitly and automatically handled by a scripting language such as Lua (e.g. imagine memory management).
Similarly, many more abstract data structures and algorithms are often directly provided by such high level languages, so you don't have to re-invent the wheel and re-implement it, if all you need is a standard container (think linked list, tree, map etc).
So, you can get a fairly good ROI when using a fairly abstract scripting language such as Lua or even Python, especially if the corresponding language comes with a good library of core functionality.
So, scripting is actually ideal in order to prototype ideas and projects, because that's when you need to be able to concentrate on your effort, rather than all the mechanical redundancies that are likely to be identical for most projects.
Once you got a basic prototype done, you can always see how to improve and optimize it further, possibly be re-implementing essential key functionality in C space, in order to improve runtime performance.
LUA has closures, and closures rock. For example:
function newCounter ()
local i = 0
return function () -- anonymous function
i = i + 1
return i
end
end
c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2
You can create a function and pass it around. Sometimes it is more handy than creating separate class and instantiate it.
For an example of where Lua fits better then c++ look at distributing scripts. Mush Client offers Lua as a scripting language. As shown by the link above you can do a lot with Lua to extend the program. Unlike C++ though Lua doesn't have to be compiled and can be restricted. For example you can sandbox Lua so it can't access the file system. This means that if you get a script from someone else it is incapable of destroying your data since it can't write to the disk.
The main advantages of Lua as a programming language (apart from the embeddability) are
Powerful, efficient hash table as the main data structure
String-processing library with an excellent balance of complexity and expressive power
First-class functions and generic for loop
Automatic memory management!!
It's hard to find a short example that illustrates all these. I have 191 Lua scripts in my ~/bin directory; here's one that takes the output of pstotext and joins up lines that end in a hyphen:
local function printf(...) return io.stdout:write(string.format(...)) end
local function eprintf(...) return io.stderr:write(string.format(...)) end
local strfind, strlen = string.find, string.len
function joined_lines(f)
return coroutine.wrap(function()
local s = ''
for l in f:lines() do
s = s .. l
local n = strlen(s)
if strfind(s, '[%-\173]$', n-1) then
s = string.sub(s, 1, n-1)
else
coroutine.yield(s)
s = ''
end
end
end)
end
-- printf('hyphen is %q; index is %d\n', '­', string.byte('­'))
for _, f in ipairs(arg) do
for l in joined_lines(io.popen('pstotext ' .. f, 'r')) do
printf('%s\n', l)
end
end
This example shows several features to advantage but does nothing interesting with tables.
Here's a short snippet from a Key Word In Context indexing program, which fetches context from a table and formats the key word in context. This example makes more extensive use of nested functions and shows some more table and string stuff:
local function showpos(word, pos, lw, start)
-- word is the key word in which the search string occurs
-- pos is its position in the document
-- lw is the width of the context around the word
-- start is the position of the search string within the word
local shift = (start or 1) - 1 -- number of cols to shift word to align keys
lw = lw - shift -- 'left width'
local rw = cols - 20 - 3 - lw - string.len(words[pos]) -- right width
local data = assert(map:lookup(pos)[1], "no map info for position")
-- data == source of this word
local function range(lo, hi)
-- return words in the range lo..hi, but only in the current section
if lo < data.lo then lo = data.lo end
if hi > data.hi then hi = data.hi end
local t = { }
for i = lo, hi-1 do table.insert(t, words[i]) end
return table.concat(t, ' ')
end
-- grab words on left and right,
-- then format and print as many as we have room for
local left = range(pos-width, pos)
local right = range(pos+1, pos+1+width)
local fmt = string.format('[%%-18.18s] %%%d.%ds %%s %%-%d.%ds\n',
lw, lw, rw, rw)
printf(fmt, data.title, string.sub(left, -lw), word, right)
end
I use a game engine called Love2D which uses Lua for writing games. All the system calls and heavy-lifting is done in a C program which reads a Lua script.
Writing a game in C or C++, you find yourself trying to work with the subtleties of the system rather than just implementing your ideas.
Lua allows for "clean" dirty-style coding.
Here's an example of a game object written in pure lua:
local GameObj = {} -- {} is an empty table
GameObj.position = {x=0,y=0}
GameObj.components = {}
function GameObject:update()
for i,v in ipairs(self.components) do -- For each component...
v:update(self) -- call the update method
end
end
To instantiate:
myObj = setmetatable({},{__index=GameObj})
-- tables can have a meta table which define certain behaviours
-- __index defines a table that is referred to when the table
-- itself doesn't have the requested index
Let's define a component, how about keyboard control?
Assuming we have an object that does input for us (that would be supplied C-side)
KeyBoardControl = {}
function KeyBoardControl:update(caller)
-- assuming "Input", an object that has a isKeyDown function that returns
-- a boolean
if Input.isKeyDown("left") then
caller.position.x = caller.position.x-1
end
if Input.isKeyDown("right") then
caller.position.x = caller.position.x+1
end
if Input.isKeyDown("up") then
caller.position.y = caller.position.y-1
end
if Input.isKeyDown("down") then
caller.position.y = caller.position.y+1
end
end
--Instantiate a new KeyboardControl and add it to our components
table.insert(myObj.components,setmetatable({},{__index=KeyboardControl})
Now when we call myObj:update() it will check inputs and move it
Let's say we'll be using plenty of this kind of GameObj with a KeyboardControl, we can instantiate a prototype KeyObj and use THAT like an inherited object:
KeyObj = setmetatable( {}, {__index = GameObj} )
table.insert(KeyObj.components,setmetatable( {}, {__index = KeyboardControl} )
myKeyObjs = {}
for i=1,10 do
myKeyObjs[i] = setmetatable( {}, {__index = KeyObj} )
end
Now we have a table of KeyObj that we can play with.
Here we can see how Lua provides us with a powerful, easy to extend, flexible object system which allows us to structure our program in accordance with the problem we're trying to solve, rather than having to bend the problem to fit into our language.
Also, Lua has some nice other features like functions as first-class types, allowing for lambda programming, anonymous functions, and other stuff that usually has comp-sci teachers smiling creepily.