Archive for the 'Informative' Category

April 29th 2007

Todoist+Quicksilver=Productive Organization

First, let me get to the nitty gritty for those who are here for the plugin and not my experiences. Today I’m pleased to announce that in a joint effort with Todoist.com, a Quicksilver module is available for download.

Why in the world would I care?

It may very well be that you don’t care, and perhaps you shouldn’t. Perhaps you’re the type of person who never has any problems remembering to do something. However, if you’re like me, keeping organized and remembering what needs to get done and when both at home, the office, or wherever is always a battle.

A couple years ago, I read the book Getting Things Done: The Art of Stress-Free Productivity, and I immediately “got it.” But I didn’t have a mechanism to organize things that I could stick with.

I began writing my own application, using others, etc., but recently I stumbled upon Todoist which solves the problem in a very simple and elegant way. It’s not exactly a purist implementation of the GTD philosophy, but it is easy to use and powerful enough for my needs.

But I still couldn’t get used to it — it required a visit to the site, clicking on the project I wanted to add the item to, and then adding it. It should be simpler.

Enter Quicksilver. I tried using Quicksilver a year or two ago, but it never quite caught on with me. After recently encountering QuickSilver - A Better OS X In Just 10 Minutes I downloaded it again and began using it in my regular workflow. Putting two and two together, I knew I should write a Quicksilver module for Todoist.

I emailed the developer, and heard back very quickly. With him designing an API, I wrote up a module this weekend. I’m proud to show it off here. It’s pretty simple to use. Edit: There is now a Quicksilver integration guide on the Info page in Todoist.

The usage is pretty straightforward if you’re a seasoned Quicksilver user. If you’re just beginning, bring up Quicksilver’s window using the keyboard shortcut assigned in the preferences. Type a period (”.”). This switches Quicksilver into text entry mode instead of searching mode. Type in the item you want to add to Todoist. When you’re done, press Tab.

Now, find “Add Todoist item to…”. This usually can be done by simply typing “add”. Once selected, press Tab again.

Lastly, either type in the name of the project you want to add this item to or simply use the arrow keys to navigate the list. When complete, press Return. You’ve just added an item to Todoist.

For me, this is the last key in my puzzle for searching for an easy way to remain productive, but still be able to quickly note things as they come up.

Not working right or want something added?

This plugin is a work in progress, mainly with the graphical aspects. Not being a designer myself, I’m doing the best I can. Any bugs or feature requests for this module should be sent to me and not to the fine folks at Todoist.

Good luck, and happy lifehacking.

Since posting this, a few bug fixes have been made. The current version for download is “A0″. If you have an earlier version, please download the latest version.

27 Comments »

November 29th 2006

Some great articles

Here are a few things that I’ve read over the past month or two that I thought everyone here would be interested in. Enjoy!

Stroustrup on software development. Bjarne Stroustrup is the person who designed C++, and he offers some insight to his personal feelings of software today, languages, and more. My favorite quote:

… There are just two kinds of languages: the ones everybody complains about and the ones nobody uses.

A short, but great read.

Steve Jobs’ commencement speech at Stanford. He challenges Stanford graduates to “Stay Hungry, Stay Foolish” by recalling three stories of his life. A wonderful speech that should inspire all of us.

Getting Software Done. This article talks about the book Getting Things Done by David Allen and relating it back to the software development process. I’m a big believer in GTD, and you can get the book on Amazon for just a hair over $10 through the link above. I’m working on a todo application that I plan on releasing in January that encourages the GTD philosophy. It’s called, “The art of stress-free productivity,” and after a few weeks of using it myself, I can honestly say that it works wonders.

Nine things developers want more than money. While this article clearly is written for management, it also can help pinpoint what you like and dislike about your job. Give yourself a point for each item that is well done, and monitor the score over the course of time. If you see your score dropping, make sure to bring up why you’re unhappy with your managers. Nine times out of ten they would much rather keep you happy and productive rather than see you move on to another company. Best of all, these things don’t require more money, just a bit of creative thinking on their part!

I hope you’ve all enjoyed these reads. Are there any good articles relating to work/development that you’ve come across recently? If so, leave them in the comments section to spread the wealth.

Comments Off

October 17th 2006

bool vs Boolean

This mostly affects plugin authors, but it also does affect any REALbasic users that are writing declares that have structures containing the “bool” datatype.

For plugin authors, you must be careful of what you put in the structure you use to represent your control or class’s data. The sizeof( yourStructure ) must be the same on all platforms because the IDE can only gather information about the one the IDE is able to load. For example, if the sizeof( yourStructure ) on Windows is 72, and on the Mac, it is 86, there will be problems when building on Windows for the Mac because the IDE will tell the compiler that your object is only 72 bytes large, and on the Mac it will promptly overwrite that buffer.

How does this size-mismatch happen? The most common cause is definitely the use of the C-Preprocessor inside of the structure declaration. This is common because on the Mac your control may have an HIViewRef while on Windows it will be an HWND, or you may need extra data on Linux to represent your control. There are two good solutions to this. The first is a little more fragile, which is to simply add padding by adding dummy variables to your structure where needed. The second is the preferred method if you’re writing a C++ plugin: make the structure only contain a pointer to a C++ class that you create in the class/object’s constructor. This allows you to easily use the bridge pattern as well to separate platform-specific logic.

The other cause is less common but harder to debug: Let’s examine this structure:

struct {
  bool mEnabled;
  REALstring mTitle;
};

Now, this structure is the same on Windows, Linux, Classic PEF, Carbon PEF, and Carbon Mach-O i386. However, on Carbon Mach-O PowerPC, the bool datatype is 4 bytes long, as opposed to 1 byte. In this situation, I urge you to use the Boolean datatype. It’s a built-in typedef on the Mac, and the SDK defines it for Windows and Linux. It will be the same on all platforms, which will alleviate these problems.

These small issues may not sound like a huge deal, but buffer overruns can yield endless weird issues, the most obvious being crashes.

Comments Off

July 31st 2006

Useless fact

Banging your head against a wall uses 150 calories an hour.

3 Comments »

May 16th 2006

Fun Algorithm Problem

Last night I was updating a piece of software that I needed to come up with a better solution for pairing things up. Once I had properly diagnosed that was the problem, I saw that I had a problem that I hadn’t ever solved before — you know, the best kind of problem to have :)

Well, it didn’t take me very long to solve it, but I thought it would be an interesting post here. So, here’s an analogous situation to what I had last night:

Problem: Every square has a list of colors, and every circle is filled with a color. Each square must have a circle connected to it, but can’t have a circle that is of a color that isn’t in its list. Not every circle must be connected to a square. Given an array of squares and circles, find a valid arrangement of connections.

Solution:

Continue Reading »

6 Comments »

January 18th 2006

All That Mac Terminology

The Mac has had a very transitional past, and a lot of things have come and gone. In the midst, we’ve seen different processors, APIs, file formats, and OSes. REALbasic supports a lot of the Mac heritage, and thus it is sometimes confusing to hear these terms thrown around. Hopefully this post will clear up any confusion that people might have.

Processors

  • 68k: The processors that drove the Macintosh platform from day 1 were stack-based processors that had some unique characteristics about them. System calls were done with software exceptions, which was actually quite efficient in that day. If you remember in REALbasic, you could specify an Inline68k string on a Declare statement — that was the 68k assembly code that raised the exception. Motorola is still using 68k processors, re-branded as ColdFire, as solutions for embedded solutions that require low-power ratings.
  • PowerPC: These RISC processors helped get the Macintosh to where we are at today. Arguably, the architecture is better, if only because it’s so much cleaner. RISC stands for Reduced Instruction Set Computer, which means that the complete reference manual for the PowerPC architecture doesn’t require several volumes to span, but rather a small-ish book will suffice (of which I have one sitting on my desk). However, it’s not because of the merits of the architectures that Apple has switched. PowerPC I expect will continue to be around for some time in many forms (just not the Mac form in the near future).
  • x86: The x86 architecture describes a very large series of processors. Not just Intel, but also AMD. The x86 name arises from a long series of processors that were all ended with the suffix of “86″: 8086, 80186, 80286, 386, and 486 (list of processors attributed to Wikipedia). On a side note, the day the Intel iMacs were announced, Apple’s stock ended the day at $80.86. These processors, while much more complex in instruction set, also are a respectible platform. Now, all major personal computer brands (excluding gaming consoles, if you count those) are looking to be x86 within the next couple years.

Operating Systems

  • System VersionNumber: The old name of the operating system was simply “System” followed by a version number. This lasted until it’s final version, 7.6.1. In these days, the only APIs around were called the “Toolbox”, and almost all of the system code was written for the 68k processors. However, in the System 7.1 days, PowerPC computers were introduced.
  • Mac OS 8.0-9.2: These versions of the OS were very transitional. Carbon was introduced in 8.1 (IIRC), and applications began adopting it. This was a huge undertaking, but Apple knew the future was going to be different, and at the same time programming System 7 and prior was quite a nightmare. Things got much better in these days.
  • Mac OS X: This is the OS we’re using today.

Application Programming Interfaces (APIs)

  • Toolbox: The Toolbox terminology has evolved. Originally, it meant the set of system calls available on the earlier Macintosh days (pre-Carbon). However, it’s a catchy name, and has evolved to be used in even current contexts
  • Carbon: This API was originally called a transitional API. However, once Mac OS X came out, Apple rebranded it to be a peer to Cocoa on the Mac. The downsides to Carbon over Cocoa didn’t mean too much in the earlier days, but Carbon continued to evolve into 10.3, where HIViews were finally stable and complete. One transition after another (QuickDraw->CoreGraphics, control manager to HIVews, WaitNextEvent->RunApplicationEventLoop/ReceiveNextEvent) makes it hard to support older systems while being a good citizen on the latest systems. It’s not impossible, but quite a bit of work.
  • Cocoa: This API is Mac OS X only. While it’s written and exposed through Objective-C (a programming language), it can be utilized within other languages. This API has been around since the days when Mac OS X was NeXT.

Executable Formats

  • PEF: Named the Preferred Executable Format, it’s actually not preferred anymore. It continues to work today on Mac OS X, but you cannot build an Intel-native version of your application using PEF. PEF was the only way to deploy applications before Mac OS X, and if you built a Carbon-PEF application, it would run natively on a PowerPC Mac OS X machine.
  • Mach-O: Mach-O, short for Mach Object, is the native executable format on Mac OS X. It’s not really that special — it’s what has been native to NeXT for a long time, and that’s the way it continues to be. To build an app that works on an Intel Macintosh, it must be built in the Mach-O format.

So, now the interesting parts — these technologies are all separate entities. Cocoa and Carbon applications can be built as Mach-O (Cocoa Mach-O, Carbon Mach-O) and both can be built for PowerPC, x86, or both (universal). Carbon can be built as PEF, but not Intel. Because of this, it’s incorrect to say something like, “This doesn’t work in Carbon, but works in Mach-O.” Because Carbon is an API and Mach-O is a file format, they are incompatible statements. The correct way to say it would be, “This doesn’t work in PEF, but works in Mach-O.”

And to answer one question that might be asked, yes, it would be possible to build a Cocoa PEF application. Because Cocoa is simply an API, it can be called from any executable with a proper Objective-C bridge. The only extra layer is transitioning between Mach-O and PEF, which is easily done. When I first wrote the core bridge code for Cocoa in REALbasic, I realized that with a little extra work REALbasic could actually build Cocoa PEF applications. However, Cocoa PEF applications wouldn’t be useful in any ways — I’m just using it as a point that PEF and Mach-O don’t determine what API you’re using.

Hopefully this cleared up the confusion on what Carbon, Cocoa, Mach-O, PEF, and how they relate.

8 Comments »

October 23rd 2005

Evening at Adler Aftermath

I got back yesterday afternoon from my very quick trip to Chicago. I stayed at the Travelodge downtown, and had a nice (but chilly) walk to the Adler planetarium. It was a bit longer of a walk than I was expecting, but due to being right next to Lake Michigan it was a beautiful walk. I got in and sat down towards the back. I then realized that Jonathan “Wolf” Rentzsch was on the panel, and he and I knew each other from ADHOC/MacHack of years past. Since I missed him at this year’s ADHOC, I decided I would go an say, “Hi.”

He was sitting next to Brent Simmons of Ranchero software, the makers of the best RSS reader for Mac OS X. Of course, I didn’t know who we was at the time, but Wolf and I talked for a bit, and I went back to take my seat. A few minutes later, I noticed Bob Kuehne walk in — he’s a great guy that I met at ADHOC this past year, and worked temporarily on a window server hack with (he had to leave early to present a session at SIGGRAPH). He took a seat up front, and since I was sitting alone at that time, I went and sat next to him and caught up.

Pretty soon, the forum began. Some familiar faces formed the panel, including (from left to right) Rosyna from Unsanity, August Mueller of Flying Meat, Inc (author of VoodooPad), Jason Harris (ShapeShifter), Paul Kafasis (Rogue Amoeba Software), Wil Shipley (Founder of the Omni Group, co-founder of Delicious Monster), Brent Simmons (Ranchero Software), Jonathan “Wolf” Rentzsch (author of Mach_*), Nicholas Jitkoff (author of QuickSilver), Bob Frank (Apple, founder of Chicago’s Cocoa And WebObjects User Group), and Eric Peyton (Apple, original creator of Fire — the chat application, not the thing that burns you).

Part of me wished I was on the panel. The other part of me just enjoyed sitting and listening to their thoughts on different topics, including the business aspects of being a small developer for the Macintosh. DRM was discussed, the future of computing and computer languages, the joys of unit tests and frameworks (Wil Shipley’s blog has had controversial discussion about these topics, so they were brought up). There was a short intermission halfway through, and I ran into a few people I knew from ADHOC during it.

Afterwards was a social gathering with alcoholic drinks and food at Jaks Tap, in a reserved room for us. Of the roughly 225+ attendees (there were still a few open seats in the audience), I’d estimate a good 100-150 showed up. Bob and I were walking to attempt to hail a cab when one of the people in the group next to me asked if we knew where we were going. I didn’t, but Bob did. He explained it, and then come to find out, said person had a car and ended up giving us a lift.

We were one of the first people to show up at Jaks, and the waitress was taking orders. I hadn’t had anything since a small meal on the airplane at 11:00 earlier that day, so I ordered a great BBQ brisket sandwich with fries. The waitress was wanting to have the person organizing the event make an announcement. The conversation was something like:

Waitress: Do you guys know who’s in charge of this event?
Us: (Pause) (Slight laughter) Well, yes. His name is Drunken Batman. (Laughter)
Waitress: (Laughs) That’s the same name I got before. I was hoping someone actually knew who he was.

Hilarity ensued. For attempting to serve a group as large as ours without fixed seating arrangements, she did a wonderful job. Sure, I didn’t get my root beer until the third time I asked, but she was getting towards her wits end. And when I did get my root beer, it was the best root beer I have had in quite some time ;)

While standing there, another person walked in who Bob and I both immediately recognized. Yet another person that I had known from at ADHOC. He joined our group of six gathered around this table, eating food and discussing various topics. I haven’t had this much geek fun since back at ADHOC.

At around 2:00, Bob (who coincidentally was staying at the Travelodge as well) and I decided to call it an evening and split a cab back to the hotel. On the way out, however, I finally ran into Drunken Batman again. I had attempted to start a conversation a few times because I had emailed him before the event offering a helping hand. I finally introduced myself, and we talked for a moment. A few minutes later, I was headed back to the hotel to grab 4 hours of sleep before getting up and heading out the door back to the airport.

It was an incredible time, and I’ve already commented on the Drunken Blog saying that I truly hope it happens again in the future.

Comments Off

September 6th 2005

Labor Day Weekend Fun

Well, as you read below, I released Morphe Beta 1 on Saturday. I since have added error tracking, and rewrote the generator quite a bit to generate smarter code, as well as put in some comments to help me debug it :) I’ve updated my Infix grammar (ie, a grammar to evaluate an expression using the order of operations we’re all familiar with — 2 + 3 * 3 = 11 is 2 + (2*3) not (2 + 3)*3). However, it’s time to head into work, so those of you using Morphe, bear with me, I plan on releasing what could be a non-beta version this evening.

I got sidetracked yesterday by a small, paying job that took a bit longer than anticipated. I had to port C code to REALbasic that had many portions that looked like this:

z = (((((( A( seed ) * 0x9E3779B1 ) ^ B( seed )) * 0x9E3779B1 )
    ^ C( seed )) * 0x9E3779B1 ) ^ D( seed )) * 0x9E3779B1;
n = (((( z ^ ( z >> 8 )) >> 16 ) ^ z ) ^ ( z >> 8 )) & 0xFF;

To make matters worse, A, B, C, and D are macros :)

I was chatting with a friend of mine, and pasted some code that was annoying me, and a few pieces of it turned into emoticons. I remarked, “Yeah… when code turns into emoticons, you know it’s too complicated.”

Anyways, now that’s done, and Morphe is progressing nicely. Thanks for all those who sent me an email expressing interest! Keep me up to date on what you’re using it for. The joy of writing something that others use never ends when you get to see and hear about all the cool things they do with it.

No Comments yet »

September 4th 2005

Morphe Beta

For the last few weeks, I’ve been creating part one of a project I’ve been wanting to work on, and I’ve decided to release a beta of it today for people to play around with. Morphe is a parser generator for REALbasic. I’m going to let the homepage speak for itself, and refrain from copying content into this post :)

There’s actually several projects that I’ve had on mind that I haven’t wanted to tackle because I didn’t feel like using Bison to create a plugin to do the parsing, or even worse, writing a custom parser by hand for each situation. Also, Bison has a rather steep learning curve, and even when you feel like you’ve gotten used to it, you still have to think very hard about how to structure your grammar.

Morphe is much easier, IMHO, than Bison, and best of all, it generates a REALbasic class to do the parsing. So, I can now proceed with my projects without resorting to writing a plugin.

It’s still beta because there’s a few things it’s missing, namely error reporting. I’ve been trying to decide how to handle error reporting, and I have a good idea, but haven’t figured out if it will work that well or not. Also, there’s a few things I can do to optimize the code it outputs, but I wanted to use larger grammars on it before figuring out what to spend time optimizing.

Anyways, have fun with it if you try it out. Let me know what you think.

No Comments yet »

August 30th 2005

Using Class Interfaces for Fun Scoping

I’m about to reveal to you a very cool feature that not many people know about. Or perhaps I’m fooling myself, and it’s known, but I didn’t realize it. Let me just dive right in with an example:

Interface TimerCallback
Sub TimerAction( t As Timer )
End Interface

Class Foo
Implements TimerCallback
Private Sub TimerAction( t As Timer )
MsgBox "I got called!"
End Sub
End Class

Now, something subtle just happened. What was it? I just implemented an interface using a private method.

(dramatic pause)

What does that mean exactly? Well, it means that you can implement an interface with any scoping you’d like to. This provides some great possibilities. The most obvious being that since you can do this, people can’t see TimerAction in autocomplete for Foo, nor can they access it without casting to a TimerCallback first. This allows you to specify your public interface for a class, without resorting to undocumented hacks (which I will leave undocumented here too :)).

So, let’s flesh out the above example. We have this class that will now throw up a message when this method gets called. Let’s create a timer that talks to things through the TimerCallback Interface.

Class CallbackTimer
Private mDelegate As TimerCallback
Sub Constructor( deleg As TimerCallback )
mDelegate = deleg
End Sub
Sub Action Handles Event
mDelegate.TimerAction( Self )
End Sub
End Class

Now, when you create a CallbackTimer, you pass in the instance of Foo, and it can call the TimerAction method. However, without having to typecast elsewhere, no one else can call this method.

This feature can be used to design some cool mechanisms for communication amongst classes. If you’ve used this, let me know what cool things you’ve come up with!

1 Comment »

Next »

  • Current Status

    • Life: Jonathan tweeted Another order from @zappos upgraded. All my orders have been upgraded to overnight... lucky, or is this standard? (Updated 15 hours, 15 minutes ago)
  • Pages

  • Meta