Older blog entries for elanthis (starting at number 54)

C++ Foreach Loop

I got my C++ foreach loop working almost 100%. Go me!

code is here

It makes use of one GCC extension (altho it's popular in other compilers), namely the typeof() construct. Unfortunately, there are some "bugs" (or just poor design) that creates a couple buglets in my code.

First off, the foreach() construct can't be used as a single statement. I define a macro foreach, and that is forced into two statements: a typedef and a for loop. I have to have the typedef because I can't do anythign like typeof(expression)::identifier, but instead have to do typedef typeof(expression) my_type; my_type::identifier.

Furthermore, typeof() seems to have mixed results when the expression given is a class constructor invocation. In some cases, it gives back the class (the "return" type of the constructor), while other times it gives back the constructor's function signature (which isn't what I want). That can, at least, be worked around by using a function or static method that just returns a constructed object for you. It's still a bit of a pain, tho.

In any event, the code does work amazingly well. I even have an STL wrapper, so you use code like:

vector<int> int_vector; ... foreach(i, STLIterator(int_vector)) cout << *i << endl;

You may notice the *i - it's a small necessity. The i variable isn't actually an int, as one might expect, but an iterator wrapper that I had to use to keep the foreach() loop down to one for loop (and the typedef I hope to find a way to get rid of). So you need to call *i (or i->) to get to the value.

The code also properly supports iterators that use references, so it doesn't have to copy values around. (i.e., it's safe to iterate over a list of large or copy-expensive types.)

The interface for custom iterators is very simple. Basically, you just derive from an Iterator<T> template, where T is the type you return on each iteration. You then define an Iterate method, which takes a "magic" out parameter, and returns a bool. You return true and set the out parameter and each call, or just return false if the iteration is over (end of list).

The base Iterator class makes the Iterate() method a virtual method. I did this only because i wanted an abstract virtual method so the compiler will complain with a nice error message if you don't define it in your subclass. It doesn't need to be virtual otherwise, tho, and it would cut down on object size for most iterators if it wasn't virtual (the template code will handle the inheritane fine), which is a good thing even if GCC should optimize out the virtual call to a static call at compile time.

Iterators do go thru one copy on call to foreach(), which is necessary in the case of temporary objects, altho I could probably find some template magic to get rid of the copy in cases where it's not needed. Ah well. ;-)

All in all, it's quite cool. If I can get some portability tests (or reports from others), I might even package it up a little nicer and release it under a BSD license or some-such, as it certainly can make C++ coding a lot more pleasant. (Even if just used to wrap STL iterators - those loops get *ugly*.)

AweMUD

I'm hoping to get AweMUD 0.19 and related libraries released this weekend. Reports show it is pretty stable on Linux, and I've also received confirmation that Cygwin support is working, so that (along with the many cool, awesome new features) will make for a great release.

I'd love to double check that Mac OS X works, as well, so I can add it to the "officially supported" platforms list for the release.

Right, so this is my first post using Gnome Blog, a really cool GNOME2 applet written in Python for quick and easy blogging. (Gods, that word is starting to grow on me - help!)

I've started yet another project, which was probably really really dumb of me given my time constraints, but at least with open source there's no schedule I have to force myself to. The project is Holy Thunder Linux, a mini-distro for developing and experimenting with MUD software, designed for users who don't have real Linux/BSD/UN*X systems about. After my experience with Arch Linux, my dissatisfaction with RedHat's retreat from the consumer distro market, and the lack of any good GNOME based desktop distro, I've had an itch to work on a solid, non-commercialized end-user distro. Holy Thunder is not that distro, but it will be some good experience under my belt for when the time comes. ^,^

Also hoping to get AweMUD v0.19 out this weekend-ish. It's been too long since the last release.

I've also been tinkering with the idea of writing a Scriptix foreach() style operator for C++. I'm not sure exactly how feasible it will be; I'm quite sure I'll need to use a mixture of macros, templates, and GCC extensions. I don't particularly care, tho, since it's more for fun than serious usage. If I do things right (and it's possible), it won't even be necessary to specify types, but will instead use template magic and typeof() to pull off type auto-detection. So one might be able to write something like:

foreach(item, myObj.all_valid()) { cout << item << endl; }

I didn't see anything like in the BOOST library, which indicates it's probably not possible while avoiding gross macro usage and keeping portability, but again, I don't particularly care. ;-)

25 Aug 2003 (updated 25 Aug 2003 at 00:25 UTC) »
Cleaning

So I've done a bunch of cleaning in the house lately, along with some furniture rearranging, trashing of old/gaudy/broken furniture, and rewiring some network drops.

It's nice, as I finally have a computer in my room (aside from just in the den/office) so I can get privacy when the other people living here start irritating me. Which, with the new proximity of my younger sibling's desk, may be much more frequent.

AweMUD Templates

Not to be confused with C++ templates, I started on the template implementation for AweMUD. Templates being definitions of, say, an item, which is shared among multiple instances of the item.

This has been a serious pain, however. It has uglified a good deal of code, and a few problems are so far unsolvable. For example, each entity in existance has a list of "actions", which are sets of data and scripts to be run when a particular action is performed on/with the entity. Normally, you can lookup an action, and modify it if need be. With the templates, you can't just lookup the action on an entity and modify it, since you may be getting back the template's action, which needs to be static for all the instances of the template in existance.

While it's somewhat easy to deal with in C++ (one method for getting a const pointer to the action instance for using it, and another for getting entity local action instances for editing), it gets much more complicated when we realize we need to support Scriptix, as well. Scriptix can't differentiate between const and non-const data, especially given how pointers are cast and encoded to pass around in the VM. The only workable solution there is to make two different Scriptix types, one for const actions and one for non-const actions, which is just an ugly solution.

I don't think there is a solution, tho, which will leave everything as clean and pretty as I like my code to be. Drat.

Blackout

So, yes, it was most miserable. They (the power company) told us it might have taken until tonight to get power on, which rather worried me - four days with no power is rather gruesome for a true-blooded geek like me.

Oops

So I've spent the whole day making massive changes to a MUD client I used to maintain (the old terminal version of MUDix, before Enigma took it back again). I was running some scripts to change the app name; namely, a script to find all occurances of mudix_ in the source and change it. Silly me had a typo in the script, and it ended up over-writing all the source files not with updated source, but blankness. Joy. 8 hours down the drain.

Java

Another MUD client project I've been working on is a web-client sort of thing. The idea is to make the UI and logic and all that in JavaScript, using HTML/CSS. I'd just use a Java applet for the actual network communications.

The problem is, I don't really know Java that well. This applet writing attempt has been a large lesson in humility.

8 Aug 2003 (updated 14 Aug 2003 at 14:30 UTC) »
I Have Returned

I am back from my vacation. And, as I rather expected, that sucks. ;-)

The trip was, for the most part, absolutely wonderful. I spent the week with my best friend in Seattle, seeing sights and otherwise just "hanging out." There were a couple things that were pure torture (which I must refrain from mentioning in the event she reads this ;-) but again, the trip as a whole was wonderful. I'm very very sad it's over already.

One thing I learned tho is just how much living with the parents sucks. I really really need a raise so I can afford to live somewhat on my own, with other people my age, doing other-people-my-age stuff.

Another thing I learned is that I'm attribute to homosexual males. This is just my luck, yes? I'm not against them or their life style or anything, just I find it rather irksome that the only person in a year to hit on me is male.

Coding

Despite having taken my laptop, several useful textbooks, and setting up a wireless connection at my friend's house, I managed to accomplish absolutely nothing on my vacation so far as coding goes.

I planned on borrowing my friend's PowerBook while she was at work to do OS X porting work on Scriptix/AweMUD, but the lack of time combined with my unfamiliarity with OS X made that not happen. I think I'd need to install the Fink utilities to get a real build environment, but I didn't want to start messing around with that kind of stuff on someone else's machine. Guess I still have a work-related excuse for buying a Mac, then. ;-)

School

Silly me forgot to take my psychology textbook with me on my trip. I'll just have to play catch-up this weekend. Which rather sucks, because (oddly enough) I really need an emotional and physical rest after my "relaxing vacation."

On the upside, it's a good subject to be studying while doing said recovery. ;-)

Preparing

Way too much preparing yet to be done for the trip. I hate being last minute, yet I always am.

Type Extending

A nifty new feature I added to Scriptix today is the abilit to "extend" a built in type. For example, take the AweMUD Player class. It represents the information of a connected player, and controls the telnet connection as well. Now, say you want to add a new feature to Player - like a method to nicely print out a health/damage report. Before, you'd have to do things the C way: make a global function, take a player as the first argument, and so on.

Now, tho, you can just "extend" the Player class. Extendign just lets you add (new) methods to an existing type. So you can add on the show_health() method.

Because of the dynamic way Scriptix works, you still need a self parameter (similar to Python) in order to get the player into the method. Which makes it still not as convenient as C++. But, at least, you don't pollute the global function namespace, and you can type something nice like player.show_health() vs. player_show_health(player) to invoke the method.

Modules vs. Headers

Looking over projects like Mono, D, and some other C++-ish modern language, I'm seeing a recurring theme of using modules vs. headers.

With a module, you put the class declaration and implementation together. This way, you don't have to worry about keeping header files and implementation files in synch.

Most of these new languages claim to help development by making it easier and speedier, and so on. However, this module approach has a big flaw that makes development a bit less pleasant. That problem is compile times. Long compile times after making changes is a huge problem with development of large applications.

In the separate declaration and implementation model, one only has to recompile code dependent on a class if the declaration changed (the header file has been modified). The code needs to make sure it worked with the new ABI (layout of structure fields and such). This is the best you can get; code must know when the ABI changes, and has to be recompiled to use a new ABI.

The separatation, however, lets you change the implementation of a class without recompiling any other code that uses the class. Which is great, because a good deal of bug fixes and tweaks and the like only require implementation modifications.

If you're using a language like D or C#, tho, the compiler can no longer differentiate between an implementation and declaration change, since the declaration and implementation are merged. So if you tweak a little value in a method implementation, you now have to recompile any and all code that uses or refers to that class. Compilation times are killer.

There is a solution, tho; one which, unfortunately, doesn't seem to be in use yet.

There is a "precompiled headers" feature in many C++ compilers. The idea of a precompiled header is to build the ABI definitions from a header once, and all source files that include the header can just let the compiler reuse those preprocessed ABI definitions, versus the compiler having having to redetermine them for each source file.

With the module system, this is already done. Source files include other modules which are already compiled. (Or recompiled when included.)

The solution to the compile time problem is to store these precompiled ABI definitions in the resulting object files. I.e., if mycode.cc includes a precompiled form of myheader.h, put the information from myheader.h in mycode.o. What does this do? Well, when we change myheader.h, it is possible that we didn't alter the existing ABI; perhaps we only added new features, or just corrected formatting. Or, even if we did alter the ABI, perhaps we altered parts that do not affect mycode.cc.

The same goes with modules. The ABI of the included module is stored in the intermediary compiled form of the dependent module.

Using this, the compiler can check whether the dependent code _really_ need to be recompiled because of the modified included code, or not. If the header change just added a few functions, none of the source files dependent on the header actually need to be recompiled. So why bother? Likewise, if the definition of a method Foo is all that changed, none of the dependent source files that don't use Foo need to be recompiled.

This kind of compilation dependency checking is really needed for module-based languages like D or C#. Without, I cannot imagine it being enjoyable to work on very large projects consisting of thousands of source files. The only other way to get around the compile time issues is to make excessive use of interfaces and the like. (An approach popular in C++, too.) Using interfaces because it makes the code cleaner is of course a very good idea. Using them because it's the only way to cut compile time down to under and hour is not so good, tho.

This feature would also be great for C++ systems too, as demonstrated. I can't count how many times I've needed to add a flag to a header file or whatnot, in which only the implementation file and one or two dependent files even use, but all the other dependent files (that don't use the new flag) are recompiled, even tho they don't change in the least.

Perhaps this kind of dependency tracking already exists? If anyone knows of any real-life compilers that use it (research projects are of no use to me, I have real work to do after all ~,^ ), I'd be most appreciative to hear of it.

ZMP

Looks like, despite me not announcing ZMP to the MUD community, it's managed to draw attention. Hopefully it'll serve its purpose well.

Thinking about it, I can only really see two weaknesses with ZMP, and both are easily worked around. The first weakness is that markup style commands, like how MXP offers HTML-ish tags, must be done using two RPC calls: a "start" command (like start-link), and then an end command after the text.

The second weakness is that there isn't a good way of handling return values from commands. Each command basically needs special return commands to make it workable, which is a little ugly. Ah well.

Web

Had some fun reworking the AweMUD website. I originally planned on going in and using just using CSS to style the page, and make it nicely accessible and all that jazz.

Problem is, I couldn't quite get things working the way I want doing that. Reading over every CSS document I could find, and drawing on my (ego aside) extensive web development knowledge, I couldn't figure out how to get CSS to manage the layout the way I wanted it. The problem being, I need absolute positioning of certain elements, and the positions of some elements rely on the positions of others. There doesn't seem to be a way in CSS to do that, unless you nest them, which, in my opinion, is worse than just using a table or three for layout. (Which is what I did.)

Some day when I have the time and inclination I'll play with CSS layout on the site some more. I know I'll have to use some "tricks" to get it working, which I wanted to avoid for now.

Games

Bought the Warcraft3 expansion to play with my friend this weekend. Of course, wonder of wonders, WineX decided to not work, yet again. That app is honestly the least reliable tool I have ever used. Yes, yes, I know trying to emulate the Windows API and environment is anything but easy, but still; when it's that flaky, even on a game they advertise it supports (neither stock War3 nor the expansion worked, altho stock War3 did in Debian), fails to run by spitting out a cryptic error message on the terminal output (and I run the game from a GNOME menu), and their touted Point2Play tool also spits out cryptic error messages on basic operation... well, why in the nine hells would I want to give them more money for updates?

I don't mind paying for software (people's time isn't free, no matter what certain zealots claim), and I don't even mind if that software isn't Open Source... but I do mind, a lot, when I pay for software that can't even perform its advertised function.

Anyways, my friend still wanted to play Warcraft, and I did rather want to play the expansion I bought, so I decided to abuse the Windows box I had borrowed (for porting), to install War3 on. And, of course, WindowsXP failed to perform its advertised function (that being "operating" the system), and I couldn't even get Warcraft installed there.

Looking at this and many other past experiences, I really think consoles are the only bright future of gaming. Linux is, well, just not there yet, and the way application installation is such a pain, and many of the core OS developers still think it's a good thing to make it hard to use my hardware with the OS (like, say, the only video drivers that work for games: nVidia), I don't think it's going to get there any time soon. Even Windows, the "gaming platform", is a complete PITA when it comes to games (driver upgrades, patches, incompatibilities, install failures, crashing, etc.).

I've not been much into consoles before because the kinds of games I usually enjoy don't work well on a console. A game like Neverwinter Nights, for example (which is on the low-end of my good games list), couldn't work well on a console because of the large amount of state needed for saved games, the interface (gamepads and thumb-joysticks just wouldn't work), and so on don't work well on a game console.

The newer console designs around may be fixing this, tho. Newer, varied input devices are possible, hard-drives will be standard (lets hope to $DEITY they aren't abused to allow patches; a strength of consoles is the quality of development and lack of need for patches), networking will be standard, and so on - a game like Baldur's Gate or whatnot could be very feasible on a console, along with the games like Zelda or Smash Brothers or so on which aren't that fun on a computer.

English

English sucks. A lot. As a MUD coder, I have to deal with it more ways than I ever wanted. Who here knows all the rules regarding the proper times to use the definite and indefinite articles, hmm? Yet, even a slight misuse thereof is quite noticable and distracting.

Other MUDs seem to deal with this problem in less than ideal ways. Some simply remove all use of articles (similar to the current lazy approach in AweMUD, which I'm trying to fix). Others always use the indefinite article, phrase their sentances that way, and ignore the fact it sounds somewhat funny. A few make builders write in all the different ways the item can be named.

The approach I'm planning for AweMUD is based on the later idea. Due to my need for sane and proper use of colour, it's important that the core part of the name be separate from the articles and such. (i.e., I want to print "the table" versus "the table", so it's clear to the player which part of the phrase is the actual name the MUD recognizes - am I spoiled by GNOME's usability standards or what?) So, each object/npc/etc. will have a name, and then a name type. The name would be, for example, "table" or "wolf". Name type would indicate whether the name is proper, unique, plural, vowel, or normal. Proper names (like "Sean") never have articles. Unique names (like the "moon") always use "the" as the article. (Unique names will, in this model, also include proper nouns that require an article, like the "King of England".) Plural names are for things like "pants" or "glasses", and vowel names for things like "adventurer" or "hourglass".

It should be possible to put in some basic automatic rules, as well. Anything capitalized will be proper by default. Anything ending in "es" or a consonant and then "s" could be plural by default. Rooms and exit names will always be unique by default (exit names are unique in each room, and rooms are places, and places often require the "the" article). Many many cases will still require the builder to specify the name type tho.

Man I hate English. ;-)

Software Packages

For all of a week, I had an interest in the Autopackage project. As many people are aware, RPMs and such just don't cut it when it comes to end-user software installation. Autopackage looked promising, but I don't think they are heading in quite the right direction.

So, I started thinking about my own packaging system, were I to write one, and how it would work. First, I came up with some goals:

  • Easy to use with a graphical installer
  • Capable of dealing with legal issues like EULA agreements for commercial software
  • Adequate dependency tracking
  • Easy to manage components

That last requirement is the one that makes my design so different from current packaging formats. Let me explain it a bit. Take a piece of software like Mozilla. Mozilla has several different components (browser, mailer, composer, chat) that can be optionally installed. In dpkg and rpm based systems, this is usually done by making one or more base/common packages, and then several component packages. It works, but it's not pretty; users have to deal with a bloated package namespace, complex or technical package names, and so on.

My solution would be to, basically, just offer sub-packages. This could even be implemented ontop of RPM, if one wanted, by using RPMs (or dpkgs) as the sub-package type. The user would open the Mozilla package, select the components she wants, and hit the Install/Remove/Update/whatever button.

The Mozilla package would also have several "hidden" sub-packages, which would be the libraries and common data stuff all the components need. Those components would not be shown on the normal user interface, and could not be removed; if Mozilla is installed, those packages are just simply there.

The scheme could be taken a step further by allowing these group/super packages to point to URLs that have RSS feeds for package updates. The system updater could look at all installed packages, read their RSS feeds, check against the GPG key fingerprint for the package to make sure it's a feed, and go from there. All the management headaches of things like APT source management go away.

Dependency tracking would also hopefully be simplified a bit. One thing that will help a metric shitload would be to simply write decent packaging guidelines, a la Debian. Libraries would have a common way of being named and packaged, for example, so they Just Work(tm). Altho libraries in general are a pain, and to make them as easy for an end user as they should be, they probably need to be rethought out on a much lower level...

It's important to note that these super packages would only be for end-user applications. Core system packages are much better suited to RPMs or dpkgs. Or perhaps a simplified package format that doesn't have all the ugly hacks and misfeatures RPM and dpkg have included to deal with user apps. ;-)

West and Seattle

I'll be in Seattle the first week of August. Any of you want to get a bite to eat or some coffee or something, let me know.

Doh, wait, I don't know any of you. Dangit. ;-)

Beattles

I never was much of a Beattles fan. Lately, tho, I'm starting to become one. I don't know what it is that now I like the music when before it irritated me, but oh well. I've had "Back in the USSR" and "Rocky Racoon" stuck in my head all weekend.

Pirates

Pirtes of the Carribean rules. A lot. Excellent movie. Seriously. ^,^

Comedy, action, romance, real plot, character development, good special effects, and likable characters make it one of the best films I've seen in a long time. Probably going to end up seeing again in theatres. ^,^

Hopefully the second time there won't be a tear in the screen, and I won't be stuck next to two big noisy unintelligent constantly eating food in plastic wrappers type people, either. :P

AweMUD

As always, too much to be done.

Current big tasks I want to get done including more cleanups/stabilizations to the network/input/telent layer (it's one big ugly mess, altho I'm slowly shaping it into something lovable), to get affects in (i.e., for magick), and template stuff I've been needing to do forever now.

Template stuff is the most boring to work on, I think, but also the most exacerbating... probably why I haven't done it yet.

After several attempts at doing it, I've realized C++ just doesn't offer the OO features needed to do it the _proper_ way. And, since I'm not going to be switching to Smalltalk or Objective-C anytime soon in AweMUD, I'll just have to do it the less than ideal way. Namely, a custom template type for Objects and NPCs, and modify the base Entity type to have more virtual methods; including virtualizing a few I'd much much rather keep as nice fast inline methods. (Very commonly called things like get_name() and such.)

Angry Pixels

More and more documentation work. But this is good. I _like_ documenting things out first. Too bad I don't do that in more of my open source projects, hmm? ;-)

45 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!