My counter¶
Prerequisites: none. This is the first package, built step by step in the Getting Started guide.
This package demonstrates the minimal structure of a Sen package: a single STL file that declares one class, and one C++ implementation class. It is intentionally small so you can focus on the mechanics of writing and wiring a Sen package rather than on business logic.
The Counter class has:
- a
valueproperty that increments automatically, - a
stepproperty, set once at construction, that says how much it increments by, - a
hellomethod that prints a greeting, and - a
valueIsDivisibleByTenevent fired whenevervaluebecomes divisible by 10.
Interface¶
package my_counter;
class Counter
{
// The current value of the counter.
var value : i32;
// How much should the counter increase each cycle.
var step : i32 [static];
// Returns a greeting message.
fn hello() -> string [const];
// Emitted each time the current value is divisible by 10.
event valueIsDivisibleByTen(newValue: i32);
}
Implementation¶
// === counter.h =======================================================================================================
// Sen Infrastructure
// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
// See the LICENSE.txt file for more information.
// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
// =====================================================================================================================
#pragma once
#include "stl/my_counter/counter.stl.h" // (1)!
// sen
#include "sen/kernel/component_api.h"
namespace my_counter
{
class CounterImpl: public CounterBase // (2)!
{
public:
SEN_NOCOPY_NOMOVE(CounterImpl) // (3)!
using CounterBase::CounterBase;
~CounterImpl() override = default;
public:
void update(sen::kernel::RunApi& runApi) override; // (4)!
protected:
std::string helloImpl() const override; // (5)!
};
} // namespace my_counter
- The generated header. Sen writes
CounterBasefromcounter.stl, carrying the properties, the event and the method you declared there. - Your implementation inherits from the generated base, which handles serialisation, subscriptions and dispatch.
- Deletes the copy and move constructors.
- Called once per cycle, during the update stage. This is where the next state is computed.
- The base class declares
helloImplpure virtual, so it has to be implemented here.
// === counter.cpp =====================================================================================================
// Sen Infrastructure
// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
// See the LICENSE.txt file for more information.
// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
// =====================================================================================================================
#include "counter.h"
// sen
#include "sen/core/meta/class_type.h"
#include "sen/kernel/component_api.h"
// std
#include <string>
namespace my_counter
{
void CounterImpl::update(sen::kernel::RunApi& /*runApi*/)
{
setNextValue(getValue() + getStep()); // (1)!
if (getNextValue() % 10 == 0)
{
valueIsDivisibleByTen(getNextValue()); // (2)!
}
}
std::string CounterImpl::helloImpl() const
{
return "Hello from Sen! My current value is: " + std::to_string(getValue());
}
// (3)!
SEN_EXPORT_CLASS(CounterImpl)
} // namespace my_counter
getValue()andgetStep()read the current buffer, the snapshot frozen before the cycle began.setNextValue()writes the next one, which everyone sees once Sen commits.- Fires the
valueIsDivisibleByTenevent. Events are buffered like property changes and delivered after the commit. - Registers
CounterImplso the kernel can instantiate it. Leave it out and the build still succeeds, but the kernel stops at startup saying it cannot find the type.
CMakeLists.txt explained¶
add_sen_package(
TARGET my_counter # Name of the CMake and runtime target
MAINTAINER "..." # Who owns this package
VERSION "0.0.1" # Semantic version embedded in metadata
DESCRIPTION "Hello Sen tutorial" # Free text
SOURCES src/counter.h src/counter.cpp # C++ files implementing the package logic
STL_FILES stl/my_counter/counter.stl # STL interface file; Sen generates C++ from this
)
add_sen_package creates a shared library that Sen loads at runtime. STL_FILES triggers code
generation: the Sen compiler reads the STL file and produces the CounterBase C++ class. SOURCES
lists the hand-written C++ files compiled alongside the generated code.
How to run it¶
load:
- name: term
group: 2
open: [local.counters]
build:
- name: counterComponent
freqHz: 2
group: 3
imports: [my_counter]
objects:
- class: my_counter.CounterImpl
name: myCounter
step: 5
bus: local.counters
Run the package with:
This opens a Sen shell with the myCounter object published on the local.counters bus. You can
interact with it using:
print shows the current property values. hello calls the method and prints a greeting to the
terminal running the Sen process.