Staying on the programming topic: One of the best parts of Roundabout (previously) was the filtering mechanism: before mail was downloaded, the user could (if needed) invoke the Filter dialog box and mark which mails were going to be downloaded (or left/deleted on the server). This happened all in a thread, where connections to SMTP and POP servers were made and commands were issued, synchronously (“blocking”, so you will). The threading class that took care of this was (appropriately) named ‘TOnlineThread’ and resided in a file called TDOnline.pas.
Many times I’ve cursed the existing threading code: I spent plenty of hours fixing up the code, or rather making the code thread-safe, as in, wrapping code that calls the main-thread (the UI thread) in so-called ‘Synchronizers’. Looking through the current code, there were plenty of changes done to this unit (the CVS history only spans a short time and doesn’t count the changes made prior to January of 2005). Anyway, if memory serves well, there were issues during the sending of mail (which happened in that thread) and the update (count of left-over messages) in a mailbox (which resided on the main UI thread) and I ended up correcting the issue, soberly stating:
- FIX (Arthur): Threadsafe RefreshNodes in TDOnline + additional processing…
Which was followed by a more cryptic:
- FIX (Arthur): Sharpened the RefreshNodes/Tree traversal.
Before you click the ‘Continue’ link, you may want to have this link at your disposal, which may explain the whole gimmick below.
procedure TOnlineThread.FRefreshNodes; var BarbaraPapaNode, BarbaraKidNode : TTreeNode; begin // NodePtr has been passed by the CommandList, so // safe to use that one... BarbaraPapaNode := TTreeNode(StrToInt(NodePtr)); BarbaraKidNode := BarbaraPapaNode; BarbaraKidNode := WalkAccountChildren(BarbaraPapaNode, BarbaraKidNode, [tnFolder]); while BarbaraKidNode <> nil do begin // So we have a folder that matches, eh? // We only want to have outboxes here, so check for outbox and drafts if (PFolderData(BarbaraKidNode.Data)^.OutBox = true) or (PFolderData(BarbaraKidNode.Data)^.Drafts = true) then begin // Hipperdepick, Barbaratrick SetPXTreeNodeName(BarbaraKidNode); if BarbaraKidNode.Selected then MainForm.TreeView1Change(Self, BarbaraKidNode); end; BarbaraKidNode := WalkAccountChildren(BarbaraPapaNode, BarbaraKidNode.GetNext, [tnFolder]); end; MainForm.UpdateRepository; if MainForm.TreeView1.Selected = MainForm.RepositoryNode then MainForm.TreeView1Change(Self, MainForm.RepositoryNode); end;
I was planning to use all the names of the BarbaFamily for each (root) node, because I saw I was going to need recursion to go through all the existing items. I (wisely) decided against it. Additionally, I made a typo, but to be honest, that saved people genuinely looking for Barbapapas and ending up on the RB CVS list…
(If you’re not familiar with the ‘BarbaraPapas’, it was a French cartoon popular with kids born in the 70s. Obviously, I was not one of them. The ‘BarbaPapas’ had this one amazing talent that allowed them to transform themselves into anything, instantly. See it to believe it (Youtube))