Archive for September, 2004

September 8th 2004

Plugin Systems

One of my tasks I spent a lot of time today contemplating is a plugin system. I always enjoyed developing plugin systems. I’ve done two so far, and one more that is unreleased (upcoming product). There’s a joy that I get when I am able to define a set of functions and load up a random shared library that extends my application.

I think it’s part of my enjoyment of the lower-level of things. Sure, loading shared libraries isn’t low-level, but what I’m grasping at is I’m one of those geeks who enjoys understanding how things work.

For example, my first step into assembly/machine code was back in May when I figured out a way to declare into Objective-C frameworks in pure REALbasic code. To do that, I learned a lot about the Objective-C messaging system, as well as a lot of things about how parameters are passed in the PowerPC runtime. However, once you can do that, you realize that there’s just not much that Cocoa has to offer that Carbon doesn’t also provide.

Then an idea clicks, and you remember a few items, like the NSStatusBar. However, there’s a problem with trying to use that from a Carbon based application. The Objective-C framework needs to call back into your application, and it does so through a NSObject subclass of some sort.

So, without hesitation, I created the ability to subclass NSObject in REALbasic. I had it working, but the methods had to be global, because the parameters lined up like this:

Obj-C
objectiveCMethod( id theNSObject, SEL theSelector, … )

REALbasic
objectiveCMethod( self as Object, … )

So, I needed to somehow, at the minimal, put a REALbasic instance into the first parameter. Well, that’s register 3, so with the help of a friend that knew assembly, we constructed 8 opcodes that would basically put r3 in r4, and then put a specified address of a REALbasic object into r3, and then proceed to call the original function.

The address of that chunk of 8 opcodes was then fed to the Objective-C runtime as the real address of the function. After many long hours of debugging, I finally got my feeble MsgBox called from inside of Objective-C. That project was fun.

Fast forward a few months later, and I wrote the beginnings of my own PPC assembler. While I had reasons behind it, I actually put that project on hold. It was mainly a fun thing to do, and I really enjoyed finding out that Motorola gives out the reading material about their processors for free :)

And this morning. Last night on a mailing list, the topic of OS X screensavers written in REALbasic came up. If no one is familiar with the API on Mac OS X for creating screensavers, it requires Cocoa. Well, there is no way around that, really. At the minimal, there has to be a stub bundle that relays messages to your application.

I wanted to take it a bit further. I haven’t been successful yet, but my idea is to basically perform the equivalent of exec (POSIX call), but not provide a protected memory environment. Why? Because then I can give it the information of what contexts to draw to and so forth. How this is going to work is a bit ugly, but it should work in the end. First, you read in all of the Mach-O REALbasic app. Next, you find the main function offset, and finally, you call that pointer.

It is a hack, in some regards, but when Apple gives you Oranges, what’s a person to do?

No Comments yet »

September 6th 2004

Automatic Wiki

For anyone using b2evolution, enjoys wiki(Wikipedia), and also tends to want to link up topics, I just finished a wiki(PHP) plugin for b2evolution that allows you to simply type wiki(SomeTopic), and it will generate a link for you! So, from now on, all the terms that I think may be beneficial for readers that may be slightly unfamiliar with the particular term can simply be turned into useful links!

In fact, this post could be considered a nice little wiki(Unit_test, unit test) ;)

Fun times… fun times…

2 Comments »

September 6th 2004

Nil Object

Well, a few days ago, I found out that NilObject.com was available. Being a wiki(REALbasic) developer, I decided it’d be a nice domain to have :) So, I purchased it.

A couple weeks ago, when I switched my personal website over to a new host, my coworker suggested namesecure.com as a registrar. I’m pretty please with them, and am happy that I moved away from having the same person do the hosting and name registration. It’s a bit restrictive, because when you want to change hosts you have to also transfer the domain.

I’ve done a tad bit of development here and there this weekend, namely furthering my wiki(Quartz, CoreGraphics) implementation in REALbasic. I previously had hit a bump when trying to pass a struct byval, because REALbasic doesn’t offer that functionality yet. I didn’t want to resort to a plugin, so I just stopped. I wasn’t developing it for any particular reasoning, other than having subpixel rendering. But, it wasn’t important enough.

Well, Mars Saxman (the REALbasic compiler writer) made an intriguing comment on the NUG mailing list, which then I researched a bit. I unearthed this article: PowerPC Runtime Conventions. The article specifies that if a struct is to be passed byval, the structure is split into 32-bit segments and placed in the general purpose registers. Well, what did I take that to mean? Simple: you can construct the structure using a memoryblock, then pass in each parameter as a memoryblock. So, an example would be:

dim cgrect as new MemoryBlock(16)
cgrect.SingleValue(0) = 10
cgrect.SingleValue(4) = 10
cgrect.SingleValue(8) = 100
cgrect.SingleValue(12) = 100

Declare Sub CGContextStrokeRect lib "ApplicationServices" (ctx as Integer, left as Integer, bottom as Integer, width as Integer, height as Integer)

CGContextStrokeRect myContext, cgrect.Long(0), cgrect.Long(4), cgrect.Long(8), cgrect.Long(12)

In this example, the MemoryBlock is filled with 4 single-precision numbers (aka float), and then re-accessed as integer values. This excited me beyond belief! So, that works for PPC, but what about X86?

Believe it or not, X86 based architectures are easier in this regard. Since parameters aren’t passed via registers, they must be passed some other way. They are passed on the stack instead. So, all parameters are “pushed” onto the stack, and “popped” off the stack in the end. So, simply declaring each parameter in turn should work. For example, if you had a struct that was made up of a float and a long, you can pass it byval by specifying the declare parameters as “f as Float, x as Integer”.

So as a result of this information, I got a lot of the CoreGraphics stuff done today. I may still turn it into a plugin, simply because any optimization freak will notice that instead of being able to fill 4 values directly and have one function call, you have the equivalent of 8 function calls before you even get to the final function call. It will be a great day with REALbasic supports structs, or as VB users would call them, “User Defined Types.”

Questions? Feel free to ask. Calling conventions can be a complicated topic, and when having to convert that knowledge into the ability to write a declare, it can be very difficult to do. However, I can look at a function and write a declare in just a matter of seconds ;) Ask, and ye shall receive.

No Comments yet »

September 4th 2004

My Evil Friday

Well, I had been putting off one of my assignments at work for a while. It involved writing something in VBA for use in Microsoft Office. Not only did I have to deal with VBA, but I had to use VBA to execute AppleScript.

AppleScript, in my humble opinion, is a [b]read-only[/b] language. It makes perfect sense when you read someone else’s code, but try to write some on your own, and frustration ensues. With Autobuilder, I was trying to get CodeWarrior to do a recursive fetch on our projects through AppleScript. Well, previously one of my coworkers had it almost working, but occasionally it failed. It was overly complicated, and should have had an easier way to accomplish it.

Thankfully, Mac OS X 10.3 introduces AppleScriptable UI. Now, instead of having to loop over every file in every part in every project and attempting to do a fetch, we can just programmatically refer to the menuitem that has always worked for us.

However, even this is ugly. It turns into:

click menu item “Fetch Read-Only” of menu 1 of menu item “Recursive” of menu 1 of top level menu “VCS”

(Etc..) Thankfully, I don’t have Script Editor open, and I don’t have to deal with AppleScript this weekend. My other complaint about AppleScript is the pain it is to enable your application to be scriptable. Despite how difficult it is, people still do it, thankfully.

Back to VBA. Although I know REALbasic, VBA is a different beast. For example, the “set” keyword. REALbasic doesn’t even have it, because it’s not really needed to form an expression. Example:

VBA:
dim foo as String
set foo = Application.GetSomething

RB:
dim foo as String
foo = Application.GetSomething

Why in the world is “set” required in VBA in that case? Okay, okay, it’s the language. I can live with that. However, not the error that I got. If it simply said, “Hey, you forgot to use ’set’,” then I would have been just fine. However, after looking at a piece of code and a cryptic error message, I finally typed “set,” and it worked. Sure, relief flooded over me, but so did anger at such a silly language construct.

Well, enough reminiscing over things that thankfully I am finished with. Everyone have a great three-day weekend!

No Comments yet »

September 2nd 2004

Complications

The product I work on during the day is an extremely complex piece of software. The build process three versions ago basically involved choosing a target in CodeWarrior, and choosing build. The target had subtargets, and it all worked wonderfully.

Next version, we added a new layer of complexity, and the build process became three steps. First, choose one target, which essentially built half of the product. Next, run a custom-made tool that converted some data generated by the first step, and then finally choose one last target and build it.

Next version, we added Linux support. CodeWarrior can’t easily (if at all) build Linux targets. So, early on in the development of this version, we realized something was going to need to be done to simplify the build process. Enter: Autobuilder.

Autobuilder is the tool I wrote that would not only control CodeWarrior through Applescript, but also sync the source files needed onto a Linux box and remotely build the files, and when done copy the file back to the main build machine. It then ran the other tool mentioned above, and then finally told CodeWarrior to wrap things up. During the development of this tool, we also hit a bump on the Macintosh version: resource forks are limited to 16 MB. We had to switch to using packages on OS X, but CodeWarrior wasn’t going to suffice to hand-tune the packages. Autobuilder added that capability as well.

And now today. The latest version has grown even more complex. Basically, the new steps will eventually make things easier, but at the moment, it’s a nightmare. To build the current version, the Autobuilder doesn’t help very much. Why? Well, let’s just say it’s sort of a rewrite. It took nearly two days for my coworker and I, who normally build the release version of the product, to get an alpha version ready for our beta testers. Something had to change again.

Enter: Autobuilder v2. I wrote Autobuilder for a very specific purpose. The code, sadly, wasn’t engineered to be flexible. I took an entirely object-oriented approach this time through and came up with what I consider a great design.

It’s based around the concept of a task. A task can contain subtasks. The GUI will provide a list of all the possible tasks, and a bunch of checkboxes. It will generate a task list, and then perform it. Why is this better? Previously, there were a few classes that handled the different actions. First, the CodeWarrior build, second the Linux build (all the code for scp, ssh, and then scp again), thirdly the manual data processing, and lastly the package processing.

Now, the task concept is being applied at a much more fundamental level. First, there are the basic tasks: AppleScriptTask, SSHTask, SCPTask, and a few others. Then there are wrapper tasks, such as a ProjectBuildTask. It is made up of one or more target tasks. One example would be a CodeWarrior target task, which is actually a subclass of AppleScriptTask. Another example would be a Linux target, which would scp the source files needed to a linux box, ssh in and execute make, and scp the result file back.

Using this design, the tasks are now not tied to any GUI choices. The only tie is the generation of the tasks, which has been improved to not be dependent on what steps have been chosen before, and which steps have been selected after the current task.

In the end, this new version will be great. However, it’s still early in development.

No Comments yet »

September 2nd 2004

Welcome

This is my development blog. If you are a reader of my personal blog, please keep comments pertaining to the separate blogs… well, separate. Also, if you know who I work for, please do not mention it in any posts. This blog mixes both personal development as well as professional development, and will remain company-anonymous.

Anyways, I’m just testing out how this blogging software works. This is the first entry I’ve made in my new blog. It’s using b2evolution, which appears to be a great, open-source blogging software.

No Comments yet »