New content are available at http://tis-method.org/. All articles from this site will be moved to the new location.

суббота, 28 мая 2011 г.

MSBuild's items indirect addressing

If you like MSBuild like i'm, you are using this tool everywere. Product deployment, continuous integration, development environment configuration, etc.

Every complex script contains a lot of items transformation steps.
Below, I would like describe one techique, that could be useful for MSBuild's script development.

Let's assume, that you need extract subset from items group with some condition.
Stardard solution could be something like this:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 <ItemGroup>
  <source Include="http://boost.org/download/boost-1.46.1.zip">
   <tag>boost</tag>
  </source>
  <source Include="http://sourceforge.net/projects/loki-lib/files/Loki/Loki%200.1.7/loki-0.1.7.zip/download">
   <tag>loki</tag>
  </source>
 </ItemGroup>
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 <Target Name="Extract">
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <ItemGroup>
   <item Condition="%(source.tag)==$(tag)" Include="@(source)"/>
  </ItemGroup>
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <Message Text="Download: %(item.Identity)" />
 </Target>
</Project>
Every 'source' item has additional 'tag' property and this value is used during item transformation.
You can specify item subset with value of 'tag' property.

As you can see, MSBuild's output shows only item with value equal 'boost' in the 'tag' property.
> msbuild extract.targets /p:tag=boost

Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.225]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 28.05.2011 16:10:16.
Project "D:\deployment\msi.targets" on node 1 (default targets).
Extract:
Download: http://boost.org/download/boost-1.46.1.zip
Done Building Project "D:\deployment\msi.targets" (default targets).

Build succeeded.
0 Warning(s)
0 Error(s)

Time Elapsed 00:00:00.05

The solution with indirect addressing is:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 <ItemGroup>
  <boost Include="http://boost.org/download/boost-1.46.1.zip"/>
  <loki Include="http://sourceforge.net/projects/loki-lib/files/Loki/Loki%200.1.7/loki-0.1.7.zip/download"/>
 </ItemGroup>
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 <Target Name="Extract">
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <ItemGroup>
   <item Include="@($(tag))"/>
  </ItemGroup>
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <Message Text="Download: %(item.Identity)" />
 </Target>
</Project>

The MSBuild's output is equal the previous.
The key element of the solution is usage "@($(tag))" expression inside 'Include' item's attribute.

воскресенье, 6 марта 2011 г.

Cross-modules Factory method


New place for this article is
here


RU
In the process of software development it is often necessary to solve the following problem: provide a transparent mechanism for binding of interacting interfaces from various binary modules.

Let's consider the target structure "from a side".

Diagram can be divided into two levels: source codes level and binary representation level.

Architecture level (source codes) contains four components, which are abstractions of the key entities («environment», «application», «editor», «engine»). The interaction between them is done through definite interfaces («ienv», «iappl», «ieditor», «iengine»).

For binary representation it is necessary to provide three configurations:
• «monolith assembly» — executable application that is used for viewing and editing data by implementing WYSIWYG
• «browser plug-in assembly»- dynamically loadable module for embedding into browsers
• «utility assembly» — utility for testing of a browser plug-in that duplicates the modular representation of a system browser-plug-in

Each level has its own key requirements:
• At the architectural level we want to see "continuous field" of interacting entities. Orthogonality of interfaces, code reuse, etc. are important here.
• At the level of binary modules the minimization of the need to recompile / build, ease of deployment, versioning and correct updates on the user side, etc come to the foreground.

The conflict of interests is obvious, on the one hand we want to get a jointless interaction between entities, on the other hand- we want to be able to assemble them in any way in the binary representation.

Each level has its own requirements and limitations. To reduce the complexity of the general task let us divide it into two parts, defining a clear interaction contract between them. On the one hand , such contract limits the combinatorial field of system types, but on the other hand it allows to minimize the "influence"of one system on another one.


Pattern
Detailed description of a pattern. In our case the implementation must hide not only the type of a definite instanced class, but also the "location" of a creator-function:
• executable module
• DLLs, "linked" at the assembly time
• delay-loaded DLLs


Recipe (howto)
First of all, define four major elements: interface, string name for the creator function, creator function type, creator function declaration. This quartet will be "visible" as contract for our interface:
// iappl.hpp
#define EXPORT __declspec( dllexport )
//
//interface definition
class iappl
{
public:
        virtual bool init() = 0;
        virtual ~iappl(){}
};

// creator function name
static char const * const create_appl_name = "create_appl";

// creator function type
typedef iappl*( *create_appl_t )( int );

extern "C"
{
        // creator function declaration
        EXPORT iappl* create_appl( int );
}


Second part is interface implementation, that consists of interface implementation and creator function definition. This implementation can be placed anywhere in the executable module or dll modules. z3d::util:fmethod will uniform interaction with interface.
// appl.hpp
//
// interface implementation
class appl : public iappl
{
        virtual bool init() { return true; }
};

// appl.cpp
//
extern "C"
{
        // creator function definition
        EXPORT iappl* create_appl( int ) { return ( new appl ); }
}

Use
Example below shows how to use template class for three possible integration mechanisms.
#ifdef USE_DELAYED_LOADED_DLL
        //dll loading/unloading
        z3d::util::fmethod creator( "core" );
#elif USE_LINKED_DLL
        // use of loaded dll
        z3d::util::fmethod creator( "core", 0 );
#else
        // use of export sections of exe module
        z3d::util::fmethod creator;
#endif
        // receive interface
        boost::scoped_ptr a( creator.lookup( create_appl_name )( 0 ) );
        a->init();

Bonus
Additionally, we can use this solution for "wrapping" functions from dll-modules.
SYSTEM_INFO si;
z3d::util::fmethod kernel32( "kernel32.dll", 0 );
kernel32.lookup< void (WINAPI *)(LPSYSTEM_INFO) >( "GetNativeSystemInfo" )( &si );

kernel32.lookup< void (WINAPI *)(DWORD, DWORD) >( "Beep" )( 750, 300 );

If you don't have or don't need define function type, you could generate it "on the fly" using
Boost.FunctionType.
namespace bft = boost::function_types;

 kernel32.call< bft::tag< bft::non_const, bft::stdcall_cc >, void >( "GetNativeSystemInfo", &si );
 kernel32.call< bft::tag< bft::non_const, bft::stdcall_cc >, void >( "Beep", static_cast< dword >( 750 ), static_cast< dword >( 300 ) );



Source code
z3d::util::fmethod

Resources
EN:

RU:




вторник, 18 января 2011 г.

Scripting subsystem based on CInt interpreter


To be compiled or to be interpreted
ru

The software system itself is a heterogeneous and multifaceted entity. It can be examined from different points pursuing different objectives. Any research like this is called to describe a new side or maybe already studied side of a particular problem, of interconnection. And received results help to deeply understand the applied problem and methods for its solution.

Below you will find the description of a mechanism of application functionality extension using CInt interpreter (interpreter for C/C++) as well as the method of unified scripts execution both in interpreted environment and in form of compiled code.


Structural application model

Starting the study of any system, first of all you need to define its structure boundaries. On the one hand it will help to avoid the consideration of undue generalized structures; on the other hand it helps not to get bogged down in details and low-level nuances, not significant at the current level. For each system there are three main elements. The first one is an environment in which the system operates, the second – is the system under consideration itself and the third is a set of nested structures responsible for the behavior of considered entity.
This is one of the equally possible partitions, but this presentation will be based exactly on this variant.

If we apply such partition to information systems, then the main connecting link of all the components will be information channels, which transmit signals/events/data in both directions. Operation system<->application<->user commands; browser<->HTML page<->JavaScript code: these are the examples of such organizational linkages.

The next step will be specifying the considered variety to the level of software systems subset. This variety is limited from below by the operation environment (operaton system), which interacts directly with the hardware. Upper variety is not limited, as the nesting of software systems into each other can be infinite (countable).
Completing the detailing stage we define the following scheme of a software system, see Figure 1.

On the one hand any system functions in some environment (Environment, Application), embeds in it (embedding). On the other hand there is a possibility to set up its behavior by means of external (Application, Configurations) mechanisms (extending).

At this level we do not make any assumptions about technologies of components creation and operation methods. These can be linkages: operation system<–>application<–>database, web server<–>php script<–>configuration file, application<–>dynamic module<–>registery parameters.


Applied application model

After specifying the structural parts, we can analyze the peculiarities appearing at the boundaries of its parts. It is logical that the operation environment must provide a broad, but a standardized interface, since it is designed for embedding of a large number of different applications. Consequently, each application created for the same environment must execute the standard contract of interaction with it. Using of rule leads to appearance of the so-called frameworks, increasing code reuse as well as development speed (here and after the framework, frame and engine are used as synonyms).

On the other hand the process of adjustment/setup/configuration can be done in many different ways: by command line parameters using configuration files, with help of interactive user input, plug-ins, scripts, etc. It is also necessary to execute an interaction contract, and in addition each of the extension mechanisms has different characteristics of generalization, versatility, extensibility etc. These are the criteria while choosing a particular tool.
Based on these conclusions we can single out the following application elements, see Figure 2.

Thus, this scheme also imposes no limitations on the implementation of each part. Framework can be written on Python, Application can be implemented as DLL on C++, and Configurations customize the system behavior using the xml file.


Scripting subsystem

As shown above, the specialization of application behavior can be carried out in many ways. Here we consider one of the options - the use of scripts as a mechanism of application functionality extension.
What is the main purpose of scripting subsystem? It is a provision of an orthogonal run-time interface to the functional system core. Interface, which deeper "penetrates" into the system compared to any operations, available through standard mechanisms of application behavior. Most packages of 2D/3D modeling, mathematical packages and financial tools contain similar functionality.
First of all we define the requirements for the subsystem to be developed
Creating of effective systems requires the opportunities for code reuse, which leads us to the following scheme, see Figure 3.

Thesis 1: Scripting code must be maximally adapted for reuse.

Different applied problems might require from us different forms of final assembly of the source codes into executable/library modules, see Figure 4.

Let us have a look at each of them separately.
First variant a) is typical for cases, when scripts run-time is critical and they are built in one module together with basic application. In such cases often the programming language of application is used for scripts too.
For variant b) the notion «application» and «framework» are not separated. These can be specialized developments for which generalization and reuse are sacrificed for the sake of speed and efficiency.
Variant c) – is an example of a monolithic system «all inclusive».
And variant d) – is a little «idealized» situation. Such structure is somewhat a standard, as it reflects a balanced view of a software product. And as usual – such result is very difficult to achieve.

Thesis 2: The implementation of scripting subsystem must enable to effectively implement four described integration schemes.

Not all scripting languages and systems can be available on all target platforms. Separate scripting language (subsystem) can be less effective compared to other language (subsystem) for specific tasks while all other conditions are equal. Figure 5 shows a schematic table of platforms covering. Using a similar table on the stage of operating environment analysis, we can select a scripting language with maximal covering and effective operation on the target subset of platforms and tasks.

Thesis 3: Scripting subsystem must provide the opportunity of parameterization by scripting language.

Now we can define the final requirement for the subsystem: developed design must be of high generality level, suitable for reuse, easily integrable, flexible, able to be parameterized by a scripting language.


C++ + CInt

This subsection is devoted to the description of really developed and used scripting subsystem, which is a part of the framework (engine) z3d.

The system is implemented in the following basis: framework – C++, application – C++, configurations – CInt.
Use of interpretation has many advantages: no need to change the binary code, broad algorithmic capabilities, usability, flexibility and unstrict typification, etc. But the speed of script execution is a disadvantage which limits the scope of its application.
Different systems "soften" this factor in different ways: the Python interpreter creates .pyc files,. NET platform performs the byte-code, Facebook «runs» php-scripts on C++.

A key property of developed system is availability of a general scheme, which enables both to use scripts interpretation and to connect them at compilation and compile them into binary module assembly.

Scripting language
CInt was selected as a scripting language. This is an interpreter for C/C++ To include CInt in project you can use compiled library from the official site. However, it is recommended to compile it from source codes using installed compiler with possibility to control the parameters of compilation and assembly.
The sequence of actions for library compilation under MS Windows with help of cygwin and msvc9 (msvc8, msvc7) is described here.

Subsystem architecture
Let us consider the design of the scripting subsystem and its component parts.
First of all, the entire scripting subsystem is implemented as a set of header files. Library user can enable them both in the executable module, and as a part of dynamic or static libraries.
Figure 6 reflects the diagram of key components.

Class z3d::script::cint::language encapsulates the presentation and behavior of a particular scripting language CInt (initialization, deinitialization, handling of context creation, etc.). Class z3d::script::cint::context - reflects a logically closed area "sandbox" within which the interpreter runs (function calls, expressions calculation). Template classes z3d::script::language and z3d::script::context realize common functionality to all scripting subsystems (context aggregation, lifetime management).
This organization allows us to meet Thesis 3 and parts b) and d) of Thesis 2.

Functionality realized in framework can be of two types:
  • interpreted code (prototypes and implementation of scripting functions of general purpose)
  • prototypes of gateway-functions for a call from scripting code. In other words, the entry points into compiled framework code from application scripts
Figure 7 shows the diagram of the source script code location.

Application: stdafx.h, stdafx.cpp
Application scripts: scr.h – a file containing general definitions for scripts and application; scr.inl – a file including all application scripts for scripts compiling; main.inl, config.inl – scripting functionality of application.
Framework scripts: engine.h – prototypes of gateway-functions for framework functionality access; common.h, vfs.h, pref.h, ui.h – frame scripting functionality; common.inl, ui.inl – implementation of framework scripting functionality.

This scheme enables to store and use scripts both on framework level and on application level and use them together in application context meeting Thesis 1.

And the last item in the list but the most important one is a preprocessor constant Z3D_SCRIPT_CINT_INTERPRETER.
If we define this constant in program code, then after module compilation all method calls of object z3d:: script:: cint:: context will be sent to CInt interpreter.
If this constant is not defined, the scripting code will be compiled and all scripting calls will be within the boundaries of compiled module. In this case the program code written on C++ and scripting code C/C++ will be compiled and assembled together.

This behavior is possible, firstly, due to certain mechanism of scripts inclusion in the project, see Fig.7, secondly, thanks to the capability of export section PE (Portable Executable).
Herein a small explanation is required. Script calls are implemented through string expressions of application time, which are delivered to the interpreter entry. In the case of "compiled" scripts the string semantics is lost after compilation. Here comes the opportunity to put the function in export section. Such mechanism works not only for the DLL, but for the EXE modules too. Thus, after module assembly you can easily recover the string semantics of a function using GetProcAddress

Here is a small illustration:
template< typename R, typename P1 >
R call( std::string const& func, P1 p1 )
{
#ifdef Z3D_SCRIPT_CINT_INTERPRETER
        std::stringstream ss;
        ss << func << '(' << z3d::type_name::param_( p1 ) << ");";
        return ( result< boost::is_float< R >::value >::convert< R >( G__calc( ss.str().c_str() ) ) );
#else
        return ( dict.get( func )( p1 ) );
#endif
}

where the function CInt – G_calc sends a string to the interpreter, and the method dict:: get returns a function pointer with name specified as func parameter, implementing the search of function by name in export section of a module.
This enables to cover parts a) and c) of the Thesis 2.

Results
This design enabled us to combine the flexibility of interpreted system and efficiency of compiled assembly. As before, the script interpreter can be included in the final program version, it can be used at the stage of design and prototyping as well as for test automation, you can consider the “scripts compiling” as their verifier, etc.
See a small example of a subsystem application below.
// create CInt language objects
z3d::script::cint::language::language_ptr_t l = z3d::script::cint::language::create( env.get_log() );

// create context (sandbox)
z3d::script::cint::context::context_ptr_t c = l->make_context();

// load script file into context
c->load( "main.inl" );

// call scripts
c->call< void >( "func" );
c->call< void >( "func1", const_cast("abcdef") );
c->call< void >( "func2", 1, 2.f );
c->call< void >( "func10", 0, 'A', 1.f, 1, 'B', 2.f, 3, 'C', 3.f, true );

Defining or removing the constant Z3D_SCRIPT_CINT_INTERPRETER you can get the script execution both using an interpreter and from a binary module.

It is also necessary to single out a number of compromises which were made while implementing the subsystem:
  • calculation of expressions will work in the interpreted assembly, but it will be unavailable in the compiled basis (calculation of expression type "2+2*2")
  • to implement the scripting function call a system was developed which compares the function call signatures and a corresponding string representation, increasing the compiling time using metaprogramming methods. f (1, 1.f) -> "f ((int) 1, (float) 1.f); "(for implementation details see here)
Among other plans of a scripting subsystem development we can single out the integration as scripting languages Ch, Python, Lua. The last two languages will not allow compiling scripts in code, but not all tasks require similar behavior. Another problem is the implementation of a “transparent” transmission of objects created within scripting code on the application level and vice versa.

Mentioned herein source codes can be obtained by downloading z3d sdk.
After installation you can find a project that demonstrates the application of scripting subsystem (msvc9) in the folder %z3d-root%/sam/. To work with the source code the libraries Boost, Loki are required.