Celtx is a free media pre-production software package. I was looking for a text editor that understood movie script formatting, and Celtx certainly does that. The Windows and Mac versions of Celtx work seamlessly together. I started my current project on Windows and am continuing on the Mac.
Those familiar with a word processor should feel right at home with Celtx. Switching between scene headings, exposition, character slugs, wrylies, and dialogue is deftly handled through tabbing and line breaks. Each scene and character introduced is added to the Master Storyboard section, a central repository for information about the story element, including the capability to store images and the like, though I have not used it for such yet.
While writing in Celtx is easy, I would request some features for editing. Sometimes I struggle with getting a particular element in the right category. It is easy to an element’s type with a dropdown, however this combined with the automatic addition of scenes and characters to the Master Storyboard can be trying. I would like the ability to scan the Master Storyboard and have Celtx prompt me to delete any elements that no longer exist in the script.
Being a programmer whose used to working with source code refactoring tools, I’d also like some “refactoring” tools in Celtx. For example, I’d like the capability of intelligently renaming a character, one that paid attention to casing, or even change the character’s gender. I’d also like the ability to rename a scene location. Going further, I could even imagine some style rules engine, maybe offering to capitalize sound verbs in some script styles.
Celtx does offer some reporting, such as showing all of the dialog. And its PDF rendering is nice. It would be nice if it showed what page number you would be on, though, as I find for pacing purposes, I’m often invoking the PDF rendition just to determine what page a particular scene is on.
For free, it suits my needs admirably, and I think their Celtx Studios online tools look intriguing. Having said that, Celtx has greater potential. I look forward to seeing the product grow.
Last time, we talked about accepting file input, the last feature added to the Object Mapper. Now, it has come time to document the module.
I use ReSharper to help code in Visual Studio, but it still doesn’t generate XML comments as well as I’d like, so I also use GhostDoc, which turns code into better English than ReSharper does. There is still editing to do, for while describing the code in English is marginally useful, GhostDoc still cannot provide context.
Finding missing documentation was trial and error until I installed the AgentSmith ReSharper plug-in, which made finding them a breeze after I turned solution-wide analysis on and marked missing documentation as a ReSharper error. Once I had all the classes, properties, and methods documented, I set out in search of a tool to convert those XML comments into something nice.
The first tool I tried was Microsoft’s Sandcastle. Sandcastle itself is tough to use, so I went to CodePlex and also downloaded the Sandcastle Help File Builder. It does a nice job of creating HTML and compressed help files (CHM).
I did have to alter a few things. I wanted namespace comments, and dug around a little before I discovered the Project Properties -> Comments expansion button on the right, and I typed those in. I did want to avoid outputting VB.NET and C++ contextual references, so I had to go into the Syntax Filters dialog and disable them. I also customized the root namespaces, help title, HTML help name, and copyright text, and I was ready to go.
But the requirement was to generate the documentation in Word. For as good as Sandcastle is, it doesn’t seem to do anything but HTML and CHM.
The next tool I tried was doxygen. It’s a UNIX tool with Windows binaries, so it took a little more cajoling. At first, it wouldn’t generate any content at all, but I got it working in short order after I saved its configuration file prior to rendering.
doxygen also supports more formats: LaTeX, RTF, and MAN pages, though it won’t do CHM. RTF is a close cousin to Word document formatting, so I had high hopes. However, I found the generated RTF document disappointing, and later found a forum where the author admitted as much.
LaTeX is a great layout specification language, so I thought it might be a decent stepping stone to a Word doc. I spent a merry while trying to monkey with LaTeX2RTF, a free converter on sourceforge, but the results were disappointing. It couldn’t understand doxygen’s custom elements.
I’m still looking for a better solution, any ideas?
The work on the Object Mapper is nearly complete from when we left off with the conversion engine.
I did enhance the parsing engine, though. My co-worker was trying to consume the engine, so he was reading in his document and extracting the text. We decided this was a common enough activity it would be worth adding to the parsing engine.
I didn’t want to pass in the filename as a string, because it would mean that the parsing engine would also become responsible for determining if a string contained a filename or an XML string. One rule of thumb is to avoid using primitives like strings to represent concepts — things with rules — like filenames. Instead, create a class to be the custodian of that knowledge.
The .NET Framework already has such a class, System.Uri. The nice thing about using a URI is that any network location can also be used, not just a filename, and I get some simple validation capability.
Integrating the URI was easy. The parsing engine wraps the input string into a StringReader and creates an XmlReader from that with which to do its work. And really, any TextReader would do, which made the enhancement easy. I created an overload that accepts a URI and wraps it in a StreamReader, which is also a TextReader. Problem solved!
Last time, I talked about the mapping document parser component of my object mapper.
The other component, the Conversion Engine, is the workhorse of the Object Mapper. Its ObjectConversionEngine class is the public interface to conversion functionality, and it exposes methods with the following signatures:
object Convert(object source)
T Convert(object source)
object Convert(object source, object target)
The first two signatures are used when constructing a new instance of the target object. The generic overload makes use of the extra type information to attempt to use .NET type converters when all else fails. The final signature is used when updating an existing target object.
When asked to convert an object, the engine will first try to locate a mapping that matches the source and target object types. If it finds a mapping, it invokes the mapping’s Command against the source object. Being a Composite, the invocation will cascade down to each individual leaf element.
I wanted to mention two things about this process. Because we may need to create an object in a multi-step process, a Source can have multiple Targets. After each Target’s command is executed, the result is cached in the ObjectFactory so it can be injected by a later command.
However, it’s easy to imagine a situation where I may want to do something conditionally. For example, if I have an array of addresses on my source type, my destination type may have a PrimaryAddress property and a SecondaryAddresses array. In this case, I want the first address of the source to map to the PrimaryAddress property and the rest to go into the array.
For this, I need a new type of command, a ConditionalCommand. The XML looks like this:
<Object Source=""System.String"" Target=""System.String"">
<If Operation=""Equals"" Operand=""SomeValue"">true</If>
<Else>false</Else>
</Object>
I thought about how to implement this for a while. When I specified this feature, I’d envisioned using expression trees. When I found out I was restricted to C# 2.0, I even spiked a version using an IL generator to create methods programatically using Reflection.Emit!
IL generation is not for the faint of heart, and I told myself there’s got to be a better way! What I wanted originally was a lambda, which thanks to J.P. Boodhoo’s Nothin’ But .NET course I knew was just syntactic sugar for delegates.
I defined a Condition delegate type:
bool Condition(object source, out object result, params object[] arguments)
And then I created a ConditionalCommandBuilder to create them. It’s really a Factory class, but I preferred the name “builder” here. It uses a fluent interface, so the If methods return a ConditionalCommandBuilder for chaining.
public ConditionalCommandBuilder IfObject(string operation, object operand, ICommand command)
{
Predicate predicate = GetPredicate(operation, operand);
Condition condition = delegate(object source, out object result, object[] arguments)
{
if (predicate(source))
{
result = command.Execute(source, arguments);
return true;
}
result = null;
return false;
};
_conditions.Add(condition);
return this;
}
The GetPredicate() command returns a Predicate, which is a delegate defined in the .NET Framework. The operation variable defines what type of predicate to retrieve, such as Equals, Exists, orGreaterThan. The operand value given to the delegate is captured for later use.
Perhaps the most interesting GetPredicate() method is the one that retrieves CompareTo() results:
private Predicate GetCompareToPredicate(object operand, ICollection compareToValues)
{
Predicate predicate = delegate(object source)
{
Type type = source.GetType();
MethodInfo compareTo = type.GetMethod(“CompareTo”, new Type[] { typeof(object) });
if (null != compareTo)
{
object converted = TypeResolver.ConvertTo(type, operand);
return compareToValues.Contains((int)compareTo.Invoke(source, new object[] { converted }));
}
throw new Exception(string.Format(“{0} must implement CompareTo(Object) to use the GreaterThan conditional”, type));
};
return predicate;
}
The TypeResolver class is analogous to the MethodResolver class I talked about in a previous post, but it finds types by name instead of methods.
One advantage to coding with design patterns is that they isolate concerns. Once I got a ConditionCommand to be created correctly, the rest of the conversion engine worked like a charm!
When running some unit tests for the Object Mapper project, I found the test suite’s execution time had slowed down noticably. I had been spoiled at my previous employer, where I had access to ANTS Profiler. So, I set about finding a performance profiling tool.
While there are some free profilers out there, the reviews on the web led me to believe they wouldn’t be up to the task. I was drawn to dotTrace because of its ReSharper integration. I decided to give it a go with their 30-day trial.
What you will read in forums is absolutely true: ANTS provides more data, with ReSharper, dotTrace is much easier to use. And, I have learned that more data is not necessarily better.
It seemed that dotTrace could not trace the code execution once it had been loaded into ReSharper’s test runner thread, so I had to write a quick console app to exercise the code I wanted to check.
dotTrace was able to pinpoint the area of code that plagued me, where I was doing some repetitive MethodInfo lookups. Some caching brought the performance back in line with what it had been.
During this tweaking process, I found dotTrace’s capability to compare test runs to be invaluable! I was able to see in percentage terms how much things improved with the caching. I also removed the caching and saw the performance degrade as expected, so I could be sure it wasn’t coincidence. And, I am happy to report that the Console.WriteLine statements in the console app were the most time-consuming piece of the process, so my engine ought be able to withstand the load I understand it will receive in production.
I strongly considering buying dotTrace when my trial expires. It’s a good tool to have in the toolbelt.
Recently, I’ve described the object mapper’s domain model and illustrated that it’s still evolving by discussing the “generation gap“. In this post, I talk about the components of the object mapper.
There are two main components to the object mapper. Since the mapper is configured via XML, clearly I need something to read in the XML and initialize the domain model. Because I’m constrained to C# 2.0, I used an XmlReader. To handle malformed mapping XML documents, I wrote an XSD schema and validate incoming XML before parsing.
Each node triggers the creation of a domain object. Each Source and Target is implemented with the Composite pattern as an Element. Sources are comprised of Targets, and Targets are comprised of leaf elements like property mappings.
Each component of the Element Composite exposes an Execute method that calls a Command. There are two sets of commands: one working on objects, the other on elements (properties or fields). For example, there is an ObjectSetter, that simply sets the target to the source. Correspondingly, an ElementSetter sets the target property value to the source property’s value.
Other types of Commands include an ObjectConverter, which invokes the conversion Function on the source and sets the target object equal to the result, and an ElementInjector, which sets a target element equal to a value specified in the mapping XML.
Array transformations are handled by way of a Decorator, which handles the invokation of the decorated Command on each element in the array.
Next post, I’ll talk about how I made some progress on bridging that generation gap.
In yesterday’s post about the domain model, I described some of the use cases for the object mapper.
In trying to use it in a real-world situation today, my co-worker found another domain concept.
Let’s say I have the following hierarchy of objects:
- Person { Name : string }
- Parent { Children : Person[] } is-a Person
- Grandparent { Grandchildren : Person[] } is-a Parent
Hopefully, that notation isn’t too hard to read. By that, I mean to say that a Person has a Name, a Parent is a Person with an array of type Person called Children, and a Grandparent is a Parent with Grandchildren.
Let’s further say that I want to use my Object Mapper to convert a Grandparent object into a Parent object.
To probe the problem, I created a new test class and started to write tests. I determined I’d need something like the following XML:
<Source ID="source1" Type="Grandparent">
<Target ID="target1" Type="Parent">
<Element Source="[TBD]" Target="Name" />
<Element Source="Grandchildren" Target="Children" />
</Target>
</Source>
The fly in the ointment is what to put in the [TBD] section. I want the name of, say, the first child.
However, even with all of the elements I introduced yesterday, I have no way of asking for elements of different “generations”, at different levels of the hierarchy. I have commands that can copy objects to objects and properties to properties, but not properties to objects or objects to properties.
Back to the TBD piece. It would be nice if it could read:
<Element Source="Children[0].Name" Target="Name" />
Children[0] is a C#-ish way of saying the first item in the array of Children, and the number is called the index of the array.
Of course, the test is red (i.e., doesn’t pass), because the Parent object doesn’t have a property called “Children[0],Name”. So far, so good.
This is really two problems in one. I decided to defer the issue of calling a property on a property (nested properties) by ignoring the Name part of the puzzle. So, I created an extra property on Parent called Firstborn, which I’ll try to populate like this:
<Element Source="Children[0]" Target="Firstborn" />
Failing test in hand, I applied myself to getting the test to pass. As I’ll explain more in a future post, I have an Adapter class that allows me to treat fields and properties the same called ElementInfo. It’s responsible for resolving properties, so I added support to the ElementInfo object to resolve indexed properties as well.
I re-ran my test. Still red.
After some debugging and head-scratching, I realized that what I really need is not support for indexed properties, but support for a property of a type that itself supports indexing, like Children which is an array.
To wit:
public Person[] _children;
// what I want to be able to extract info from
// example: mom.Children[0]
public Person[] Children
{
get { return _children; }
set { _children = value; }
}
// what I ended up supporting, oops!
// example: mom[0]
public object this[int index]
{
get { return _children[index]; }
}
So, once more into the breach, dear friends!
I now return you to the scheduled posts in the series while I resolve this. The next post will talk some about the XML parser.
Last time, I introduced the object mapper. Here, I describe its domain model.
The request and response objects that require mapping are plain-old CLR objects with properties for the most part, though there are some arrays to contend with. The challenge is that the request and response objects do not have the same structure.
Many of the properties have a one-to-one correspondence. For example, a Name field on one request object may align with a Name property on the DataStore request. In some cases, though, the property names are different.
Other properties share a one-to-many association, so the contents of the source object must be copied to several target properties. And yet other pesky properties share a many-to-one association. For example, a Java application’s request might have address, city, state, and ZIP code as separate fields, but they must be combined into a single property of the DataStore request.
Here’s an example of a simple mapping document for a Foo object with Name and Age properties:
<?xml version="1.0" encoding="utf-8"?>
<Maps>
<Source ID="source1" Type="Foo">
<Target ID="target1" Type="Foo">
<Element ID="Name" Source="Name" Target="Name" />
<Element ID="Age" Source="Age" Target="Age" />
</Target>
</Source>
</Maps>
There is a Source, which describes a source object. That Source object can be converted into a Target object. Objects have Elements, which describe either properties or fields. Each element has its own source and target attributes to describe what property of the source corresponds to what property of the target.
So far, so good. Let’s say, though, that the source request object doesn’t define an Age property, but it’s required on the target request. For cases like this, I need the capability to inject a value:
<Source ID="source1" Type="Foo">
<Target ID="source1" Type="Foo">
<Element ID="Name" Source="Name" Target="Name" />
<Inject Target="Age">37</Inject>
</Target>
</Source>
The Inject node allows me to specify the value I’d like to inject, in this case any target object would have an Age of 37.
This poses a challenge, because that “37″ is a string by virtue of being XML. .NET doesn’t offer a way to implicitly make that “37″ into the number 37. So, I need a way to convert primitive objects, objects with no properties:
<Object Source="System.String" Target="System.Int32">
<Function Type="System.Int32" Method="Parse" />
</Object>
The Function node defines a method to invoke when converting the object. It’s a valid child of the Element node as well, so a property can be converted by a function as well.
Functions can refer to instance methods, which are called against an instance of a type. They can also refer to static methods, which belong to the type itself. One can even specify arguments, for cases like Substring where I might only want the first few letters of a string:
<Element ID="Name" Source="Name" Target="Name">
<Function Type="System.String" Method="Substring">
<Argument Type="System.Int32">0</Argument>
<Argument Type="System.Int32">3</Argument>
</Function>
</Element>
Sometimes, I may want to convert an array of one type to an array of another by converting each of its members individually by use of the ApplyToEachElement flag:
<Object Source="System.String[]" Target="System.Int32[]" ApplyToEachElement="true">
<Function Type="System.Int32" Method="Parse" />
</Object>
Here, the conversion engine will take an array of strings and convert it to an array of integers by calling int.Parse with each string as an argument.
That introduces most of the domain concepts of the object mapper. Next post will delve into the components that comprise the object mapper itself.


