Home > Uncategorized > Carmenta Engine Power Pack

Carmenta Engine Power Pack

A nice property of Carmenta Engine is the duality between the script interface and the .NET interface. By duality, I mean that

  • the apis are equally powerfull (or at least to 99%)
  • an object that has been created using one api can be accessed later by the other api

The script interface is used, behind the scenes, by the visual configuration tool SpaceLab to create objects. Creating a configuration setup in SpaceLab is quick and the result is readable and maintainable. However, I would argue, the .NET interface tends to be a bit verbose and non-standard. I know that this is about to change for the next major release (a great thing) but meanwhile (and for those who are stuck using the current version) it would be nice to improve. Among the most important things that I wanted to solve was:

  • Online replacement for the two step new-create pattern (var readop = new ReadOp(); readop.Create(…))
  • Conversion from enumerations to carmenta engine collections
  • Conversions to enumerations from carmenta engine collections (using extension methods)

The Carmenta Engine API is very large, however, and it would be an immense task to write such code by hand. Luckily, Visual Studio comes with a code generation toolkit called T4, Text Template Transformation Toolkit Thus, if I could just write down the rules for how to generate the necessary wrapper code I would be in heaven. This sounded too fun not to do! And so I ended up with a library which I named Carmenta Engine Power Pack. Currently the library consists more or less of one large factory class:

namespace CEPowerPack

{

    public static partial class Factory

    {

        public static ReadOp CreateReadOp(String Name, Operator Input = null, DataSet DataSet = null, DataSetQuery Query = null)

        {

            var instance = new ReadOp();

            instance.Create(Name);

            if (Input != null) instance.Input = Input;

            if (DataSet != null) instance.DataSet = DataSet;

            if (Query != null) instance.Query = Query;

            return instance;

        }

 

        public static Points CreatePoints(IEnumerable<Point> elements)

        {

            var result = new Points();

            foreach (Point element in elements) { result.Add(element); }

            return result;

        }

 

        public static List<Point> ToList(this Points elements)

        {

            var result = new List<Point>();

            foreach (Point element in elements) { result.Add(element); };

            return result;

        }

 

        // Lots and lots of more methods…

    }

}

 

First, take a look at the CreateReadOp method. The factory contains one such method for each class and each create method and using this we can replace the new-create pattern with a one liner. Next, the CreatePoints method. The factory contains one such method for each collection class which allows for simple construction from .net enumerations. And last, the ToList method which is an extension method. Each collection will be extended by a ToList method, enabling easy conversion to .net lists.

Using this factory class the code can be significantly shorter and more readable. For example:

class Program

{

    static void Main(string[] args)

    {

        // Collection support (construction from enumerations and tolist extension methods)

        Points polygon = Factory.CreatePoints(new [] { new Point { X = 0, Y = 0 }, new Point { X = 10, Y = 40 }, new Point { X = 40, Y = 10 } });

        IEnumerable<Point> zeroX = polygon.ToList().Where(p => p.X == 0);

 

        // Factory methods

        var wgs84 = Factory.GetRefSystem("WGS84lola");

        var myDs = Factory.CreateInternalStore(Name: "", RefSys: wgs84) as DataSet;

        var geoLine = Factory.CreateGeoLine(DataSet: myDs, Points: polygon);

        var readOp = Factory.CreateReadOp(Name: "", DataSet: myDs) as Operator;

        var lineVis = Factory.CreateLineVis(Name: "", Color: Factory.CreateDirectColorAttributeVariable(0, 128, 128)) as Visualizer;

        var visList = Factory.CreateVisualizers(new[] { lineVis });

        var renderOp = Factory.CreateRenderOp(Name: "", Input: readOp, VisList: visList) as Operator;

        var layer = Factory.CreateOrdinaryLayer(Name: "", Operators: Factory.CreateOperators(new [] { renderOp })) as Layer;

        var drawable = Factory.CreateWindow(Name: "", Width:400, Height:400, X:10, Y:10) as Drawable;

        var geoRect = new Rect { Xmin = -10, Ymin = -10, Xmax = 100, Ymax = 100 };

        var view = Factory.CreateView(Name: "", Drawable: drawable, Layers: Factory.CreateLayers(new [] { layer }), RefSys:wgs84, GeoRect: geoRect);           

 

        // Test

        view.Update();

        Console.ReadLine();

    }

}

 

The library can either be used by referencing the CEPowerPack dll or by including the source files. Not all plugins have generated wrappers but it is easy to add new ones if needed. It should be noted, though, that the sample code above leans heavily on named paramters which is a new feature in C# 4.0. The entire library source code can be downloaded here.

Advertisements
Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: