NoesisGUI

Kernel Modules

As described in SDKLayer, kernel modules are implemented inside Core/Kernel. Their lifetime is managed by the kernel itself. The list of modules that are initialized by the kernel is statically defined.

ConfigManager

ConfigManager is the kernel module used to configure the entire engine (kernel modules, kernel systems and applications).

ConfigManager is filled with the entries grouped in sections of one or more .ini files located in the /Config application directory. Now, Kernel looks for 2 files with the same name of application EXE file but ending with .ini and .local.ini (for example, if exe file is /Bin/MyApp.exe, then config files are /Config/MyApp.ini and /Config/MyApp.local.ini). If application name includes project configuration name, then it is removed (for example, if exe file is /Bin/Debug.Core.Tester.exe, then config files are /Config/Core.Tester.ini and /Config/Core.Tester.local.ini). Entries in the .local.ini file will have more priority because are applied after the application config file.

The section name must be simple C identifiers, or a list of C identifers separated by dots:

[Section1]
[Section2]
[Section2.Sub1]
[Section2.Sub2]

Valid entry values are: basic values, composite values and list values

  • Basic type values: integers, floats, bools or quoted strings

    v1 = 1
    v2 = 0.5
    v3 = true
    v4 = "Hello World"
    
  • Composite values: a composite value is formed by more value entries enclosed by curly braces and separated by commas. This introduces recursion, because a sub-value can also be any type of accepted values.

    v1 = {x=0, y=1.5}
    v2 = {x="Hello World", y={a=1, b=2}}
    
  • List values: a list values is formed by more values enclosed by braces and separated by commas. This also introduces recursion.

    v1 = [1, 2, 3]
    v2 = [1, [2, 3]]
    v3 = [{a=0, b=false}, -1]
    

Comments in the config file correspond to lines beginning with ';'.

[Section]
; This is a comment in a config file
v1 = true

ConfigManager usage is simple, just ask for a section, and for a value inside.

ConfigManager* cfg = NsGetKernel()->GetMemoryManager();

// get section
const ConfigSection* section = cfg->GetSection(NST("Section1"));

// basic values
NsInt v1 = section->GetValue(NST("v1"))->AsInt();

// complex values
const ConfigValueComposite* val = section->GetCompositeValue(NST("v2"));
Vector2f pos(val->GetValue(NST("x"))->AsFloat(), val->GetValue(NST("y"))->AsFloat());

// list values
const ConfigValueList* val = section->GetListValue(NST("v3"));
NsSize numVals = val->GetNumVals();
for (NsSize i = 0; i < numVals; ++i)
{
    indices.push_back(val->GetValue(i)->AsInt());
}

It exists a NsConfig.h header file that makes access to ConfigManager values easier.

#include <NsCore/NsConfig.h>

// get a basic value, creating the corresponding entry with the default value if it didn't exist
NsInt serverPort = NsConfigValue(NST("Core.Logger"), NST("ServerPort"), NST("9000"))->AsInt();

// get a value from a composite value
NsInt alpha =
    NsConfigSubValue(NST("Cognition.Viewport"), NST("Background"), NST("A"), NST("255"))->AsInt();

// get a value from a list value
NsString key = NsConfigListValue(NST("InputSystem"), NST("Bindings"), index, NST(" "))->AsString();

There are console commands to dump ConfigManager sections and their entries:

  • Kernel.DumpConfig
ConfigManager Sections
------------------------------------------------------------------
> [Core.Logger]
  ServerAddress = "127.0.0.1"
  ServerPort = 9000
> [Core.MemoryManager]
  BreakOnId = -1
  CallStackDepth = 10
  StoreCallStack = true
  TrackMemory = true
  • Kernel.DumpConfigSection sectionName
ConfigManager Section
------------------------------------------------------------------
> [Core.Logger]
  ServerAddress = "127.0.0.1"
  ServerPort = 9000

Logger

Logger is the kernel module used to trace messages. Current implementation connects with a remote console to send log messages.

The use of this kernel module is done through preprocessor macros implemented in LoggerMacros.h. This way, the traces can be disabled in specific configurations. There are four possible log levels: Info, Warning, Critical and Debug.

NS_INFO(NST("Registered %d objects"), n);
...
NS_WARNING(NST("Parameter has a value out of range"));
...
NS_CRITICAL(NST("Critical error! System will shutdown"));
...
NS_DEBUG(NST("Current counter value: %f"), p);

The macro NS_ERROR is a bit different, because it logs a message and also signals an error.

Memory Manager

This module manages every memory allocation and deallocation done during engine lifetime.

Memory Manager is implemented using different layers that manage allocations and deallocations for specific purposes. For example, a layer could registry allocations to detect if the application terminated with memory leaks or a layer could registry memory requests to perform statistics on memory usage during application execution. These layers could be activated through preprocessor macros defined in configuration files.

Symbol Manager

The Symbol Manager stores all the symbols created. Symbols are immutable strings usually defined in compile time. In the strings section you can find a better explanation.

Reflection Registry

The Reflection Registry stores all reflection types created. Reflection types are created only when needed and only one instance for each type.

Component Factory

The Component Factory is used by DLLs to register their components. Then, registered components can be created using the factory:

Ptr<ICommon> component =
    NsGetKernel()->GetComponentFactory()->CreateComponent(NSS(ComponentClassId));

When components are registered, a category could be assigned to them. So you can enumerate all the components belonging to some category:

NsSymbol categoryName = NSS(CategoryName);
Ptr<IIterator<NsSymbol> > componentIt =
    NsGetKernel()->GetComponentFactory()->EnumComponents(categoryName);

while (!componentIt->End())
{
    NsSymbol componentName = componentIt->Get();
    NS_INFO(NST("Component: %s (%s)"), componentName.GetStr(), categoryName.GetStr());

    componentIt->Advance();
}
© 2017 Noesis Technologies