Inheritance example¶
This example shows how inheritance works in Sen.
Interface¶
There's a base class defined in animal.stl from which we have two subclasses in cat.stl and
dog.stl.
classDiagram
class Animal {
Taxonomy taxonomy
Vec2 position
advance(a, b) [function]
madeSound(content) [event]
}
class Dog {
goodDog() [function]
badDog() [function]
}
class Cat {
jumpToLocation(x, y) [function]
}
Animal <|-- Dog
Animal <|-- Cat
package animals;
// See https://en.wikipedia.org/wiki/Taxonomy_(biology)
struct Taxonomy
{
domain : string,
kingdom : string,
phylum : string,
type : string,
order : string,
family : string,
genus : string,
species : string,
}
quantity<u32, m> MetersU32;
// A position in a 2D-grid
struct Vec2
{
x : MetersU32, // Horizontal dimension
y : MetersU32, // Vertical dimension
}
// Base class for animals
class Animal
{
// The taxonomy of the animal
var taxonomy : Taxonomy [static_no_config];
// The animal position
var position : Vec2;
// Advances a steps in the x direction and b steps in the y direction.
//
// @param a meters to advance in the x direction.
// @param b meters to advance in the y direction.
fn advance(a: MetersU32, b: MetersU32);
// Emitted when the animal makes a sound.
//
// @param content the sound
event madeSound(content: string);
}
Implementation¶
We provide an implementation of Animal, and reference it in the implementations of Cat and Dog
using template parameters. With this mechanism, you can "inject" implementations in intermediate
classes of a class hierarchy.
// === animal.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.
// =====================================================================================================================
#ifndef SEN_EXAMPLES_PACKAGES_ANIMALS_SRC_ANIMAL_H
#define SEN_EXAMPLES_PACKAGES_ANIMALS_SRC_ANIMAL_H
// sen
#include "sen/core/base/compiler_macros.h"
// generated code
#include "stl/animal.stl.h"
namespace animals
{
class AnimalImpl: public AnimalBase
{
public:
SEN_NOCOPY_NOMOVE(AnimalImpl)
public:
using AnimalBase::AnimalBase;
~AnimalImpl() override = default;
protected:
void advanceImpl(MetersU32 a, MetersU32 b) override
{
const auto& currentPosition = getPosition();
setNextPosition(Vec2 {currentPosition.x + a, currentPosition.y + b});
}
};
} // namespace animals
#endif // SEN_EXAMPLES_PACKAGES_ANIMALS_SRC_ANIMAL_H
// === cat_impl.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.
// =====================================================================================================================
// generated code
#include "stl/cat.stl.h"
// package
#include "animal.h"
// sen
#include "sen/core/base/compiler_macros.h"
#include "sen/core/meta/class_type.h"
#include "sen/core/meta/var.h"
// generated code
#include "stl/animal.stl.h"
// std
#include <cstddef>
#include <string>
namespace animals
{
class CatImpl: public CatBase<AnimalImpl>
{
public:
SEN_NOCOPY_NOMOVE(CatImpl)
public:
CatImpl(const std::string name, const sen::VarMap& params): CatBase<AnimalImpl>(name, params) { init(); }
~CatImpl() override = default;
protected:
void jumpToLocationImpl(MetersU32 x, MetersU32 y) override
{
jumpCount_++;
setNextPosition({x, y});
if (jumpCount_ % 3 == 0)
{
madeSound("meow!");
}
}
private:
void init()
{
Taxonomy taxonomy;
taxonomy.domain = "Eukaryota";
taxonomy.kingdom = "Animalia";
taxonomy.phylum = "Chordata";
taxonomy.type = "Mammalia";
taxonomy.order = "Carnivora";
taxonomy.family = "Felidae";
taxonomy.genus = "Felis";
taxonomy.species = "F. catus";
setNextTaxonomy(taxonomy);
}
private:
std::size_t jumpCount_ = 0U;
};
SEN_EXPORT_CLASS(CatImpl)
} // namespace animals
// === dog_impl.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.
// =====================================================================================================================
// generated code
#include "stl/dog.stl.h"
// package
#include "animal.h"
// sen
#include "sen/core/base/compiler_macros.h"
#include "sen/core/meta/class_type.h"
#include "sen/core/meta/var.h"
// generated code
#include "stl/animal.stl.h"
// std
#include <string>
namespace animals
{
class DogImpl: public DogBase<AnimalImpl>
{
public:
SEN_NOCOPY_NOMOVE(DogImpl)
public:
DogImpl(const std::string& name, const sen::VarMap& params): DogBase<AnimalImpl>(name, params) { init(); }
~DogImpl() override = default;
protected:
void goodDogImpl() override { madeSound("wuff!"); }
void badDogImpl() override { madeSound("grrr!"); }
private:
void init()
{
Taxonomy taxonomy;
taxonomy.domain = "Eukaryota";
taxonomy.kingdom = "Animalia";
taxonomy.phylum = "Chordata";
taxonomy.type = "Mammalia";
taxonomy.order = "Carnivora";
taxonomy.family = "Canidae";
taxonomy.genus = "Canis";
taxonomy.species = "C. familiaris";
setNextTaxonomy(taxonomy);
}
};
SEN_EXPORT_CLASS(DogImpl)
} // namespace animals
How to run it¶
Let's define what we want to run in our Sen kernel.
# $schema: ../base/schema.json
include:
- ../base/shell.yaml
build:
- name: myComponent
freqHz: 30
imports: [animals]
group: 3
objects:
- class: animals.CatImpl
name: rufus
bus: my.tutorial
- class: animals.DogImpl
name: elon
bus: my.tutorial
To run it, let's call sen run:
This will open a shell and tell Sen to instantiate the cat and dog implementations in the
my.tutorial bus.
You can interact with the objects by doing commands such as:
info my.tutorial.elon.print
info my.tutorial.rufus.print
info my.tutorial.elon.advance 2, 2
info my.tutorial.elon.getPosition
info my.tutorial.elon.goodDog
info my.tutorial.rufus.advance 2, 2
info my.tutorial.rufus.getPosition
info my.tutorial.rufus.jumpToPosition 4, 4
info my.tutorial.rufus.getPosition
Running it over the network¶
We can run it over the network using the eth component. This is the same as the first example, but you will need to start two processes.
First run:
Then, in another terminal or command prompt, run:
In this new Sen instance, open the bus where we should find our objects:
You should be able to work with the objects as if you were on the same process.
Using the explorer¶
You can also run it using the explorer to see and interact with the objects in a more graphical way.
You can monitor the events produced by the instances by opening the relevant window, checking the relevant events, and looking at the event explorer window. For example, if you monitor the dog, you should be able to see events when calling the goodDog and badDog function. Same when calling the jumpToLocation on the cat.