Alan.Platform Tutorial (Part 1)

    The last time we talked about how it is not enough to create a model of the world, which will engage the brain. To test the behavior of the brain in various situations, you need to have many such models on hand. And for this, two things are needed: the first is the ability to easily and quickly create models, and the second is the ability to reuse the created models, changing their configuration.

    Looking at these requirements, I have the following thoughts:
    • modularity; loadable libraries with extensions;
    • configuration via XML;
    • representation of the model in the form of a tree of objects;
    Also, when creating the models themselves, I would like to write as little code as possible, because not one or two are needed to be lazy . Here we need to remember that the brain, when interacting with the environment, receives information from it, converts it and returns the result. The environment, in turn, receives this information, converts it again and returns the result to the brain. This is the whole point - information goes in a circle.

    Technically, one could only model information transformations. No mazes, no food, whistles and bells. There is only one object - the World, which plays with the brain in ping pong bytes. I would love to see this process, but I wouldn’t wish the enemy to create such a model.

    The object-world is a bad metaphor that does not fit into any brain. When we look at the world, we do not see information - we see objects that have certain properties. Therefore, I would like to work with the modeling of the world with the metaphors of objects and their properties. The problem is that for this you will need to write additional code, which, as it turned out, is not necessary to write at all, and generally laziness.

    Therefore, a compromise was found. Only information transformations should be described in the code, and objects with properties will be created declaratively.

    Tutorial ["Part 1"]

    This is a couple of words about why I did the way I did, end and you can proceed to practice. Last time, some ideas were shown on how the process of modeling the world might look. Today it will be a tutorial that guides you through this process from the very beginning to the end.

    For work, we need the .NET Framework 3.5, the development environment for it and the source code of the latest version Alan.Platform. First, create a solution with one class library (.dll), copy the Platform.Core project from Alan.Platform into it and add a link to it in our class library. This library will contain various elements on the basis of which the world will then be constructed.

    As is customary in the tutorials, the created model will be quite simple, but no more than required. In our case, it will be a board divided into cells. Objects will be located on the cells of the board, so their coordinates can be determined by two numbers.

    Let's start by marking our freshly created library with the ElementsLib attribute so that Platform.Constructor can use the elements defined in it:
    [assembly: Platform.Core.Concrete.ElementsLibAttribute]
    The most suitable place for this is the AssemblyInfo.cs file. Next, add to the library a new class, CellBoard, which will represent our checkered board. Let it be a board for playing checkers. Then only one type of objects can be located on it - a checker, which has two properties: X and Y. Thus, our CellBoard class takes the following form:
    using System;
    using Platform.Core.Elements;
    using Platform.Core.Concrete;

    namespace Checkers
      [PropertySet("Checker", "X", "Y")]
      public class CellBoard : Layout
        public override bool ValidatePropertySet(PropertySet ps)
          throw new NotImplementedException();
    What have we just done in reality? The brain has several channels through which it receives information of various types. Therefore, it is logical to use a separate object to manage information of one type. Such an object is an operator. Layout is a class derived from the operator, which is created to manage information of a special type - information about the location of objects.

    Location information is special because it can potentially affect other types of information. For example, if you bring a fragrant bun to us, then its smell will become stronger.

    Back to our CellBoard. The PropertySet attribute, as you might guess, declares the name of an object type and its properties. There can be several such attributes and all of them indicate with what types of objects and their properties this operator can work.

    We don’t need ValidatePropertySet yet, so let's leave it as it is. Despite the fact that there is no class implementation yet, we can try to construct something based on it. To do this, add the Platform.Constructor project from Alan.Platform, a new console project to our solution, and add a link to the designer in the console project.

    Platform.Constructor helps to create a ready-made model of the world from many elements. Using the constructor is very simple - just describe the desired end result in XML. What will we do now.

    The XML schema is quite simple. If you want to see tips for tags and attributes, you can connect it to your favorite editor. You can find the circuit in
    Alan Platform \ Platform.Constructor \ config.xsd.

    Here is the description of a 2x2 board, in the corners of which is located on a checker:





    Here we see our freshly created operator and two components (checkers) for which we did not write code at all. If someone still does not fully understand the idea of ​​a PropertySet, then imagine that this is a projection of an object onto an operator. That is, each object (component) consists of several sets of properties, one per operator (type of information).

    You may not pay attention so far that all this is enclosed in another root component. Yes, theoretically, components can be infinitely nested into each other, but it is not yet clear how this can be used.

    So, if you pass this XML document to the constructor, then it will return the very root component, which, in theory, is our checker board. To check this, we will use ObjectDumper. Add it to our console project, and do not forget to add a link to our library of elements, as the designer expects to find it in the same folder in which he is located.

    The Main function should look something like this:
    using System;
    using System.Xml.Linq;

    namespace Tutorial
      class Program
        public static void Main(string[] args)
          var constructor = new Platform.Constructor.Constructor();
          // Загружаем документ XML, адрес которого передан в консоли.
          var config = XDocument.Load(args[0]);
          // Создаем дерево модели мира.
          var rootComponent = constructor.Construct(config);
          ObjectDumper.Write(rootComponent, 2);
          Console.Write("Press any key to continue . . . ");
    It remains only to transfer to Main the address of our XML document. To do this, set the Copy to output - PreserveNewest property for it. And in the properties of the console project, specify the command line arguments - config.xml.

    Here's what you should end up with: Container - a reference to the parent component. The root component is null. Components - a set of child components. Clients is a special type of component, about which a little later. Operators - a set of child operators. Layout is one of the operators. Properties - information about the properties of the component. The root component has no properties. Id is a unique identifier. The root component is always 0, and the daughter component is 1, 2, 3, etc.

    In general, the structure of the tree corresponds to that in XML. Unless the properties of the components are not divided into sets of properties, since this is not necessary here. The components in this model are present only so that users are accustomed to seeing objects with properties.

    In fact, the brain will not interact with the components, either directly or even indirectly. It will interact with operators in which real property data is stored. And those that are in the components become irrelevant almost immediately. To update them, you will have to manually call UpdateProperties ().

    On this the first part of the tutorial ends. His main goal was to show what work with Alan.Platform looks like. Archive with the result can be downloaded here. In the next part, we will try to create a graphical representation of our checkers using Platform.Explorer.

    PS In the Main function, there is the following line “constructor.CollectElementsIndex ();”, which, as you might guess, indexes the elements. Here's how it works:

    1. Creates an AppDomain to temporarily load libraries into it.
    2. Loads into the created AppDomain all * .dlls that are in the same folder as the constructor (or rather, AppDomain.Current.BaseDirectory).
    3. Sifts libraries that do not have the ElementsLib attribute.
    4. In the remaining libraries, finds types that correspond to the elements of the world model tree.
    5. Fills the index with the necessary information about these elements.
    6. Unloads AppDomain with libraries.

    Further, the created index can be used to create a tree of elements based on XML, if necessary loading libraries in which these elements are defined. Here's what the index looks like: For those wishing to participate in the project or use it to create something, please contact the PM or knock on jabber: The second part

    Also popular now: