Compare commits
7 Commits
34f834d370
...
serializat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6068b62e39 | ||
|
|
4435776484 | ||
|
|
a1c5fc2600 | ||
|
|
9118afdd13 | ||
|
|
8e6e332217 | ||
|
|
e1bd7eb44f | ||
|
|
c0c25de694 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,3 +13,6 @@ src/Python/uLib/*.pyd
|
|||||||
src/Python/uLib/*.pyc
|
src/Python/uLib/*.pyc
|
||||||
src/Python/uLib/__pycache__
|
src/Python/uLib/__pycache__
|
||||||
src/Python/uLib/.nfs*
|
src/Python/uLib/.nfs*
|
||||||
|
test_props.xml
|
||||||
|
test_props2.xml
|
||||||
|
test_boost.cpp
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ endif()
|
|||||||
|
|
||||||
# The version number.
|
# The version number.
|
||||||
set(PROJECT_VERSION_MAJOR 0)
|
set(PROJECT_VERSION_MAJOR 0)
|
||||||
set(PROJECT_VERSION_MINOR 6)
|
set(PROJECT_VERSION_MINOR 7)
|
||||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||||
set(PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
set(PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ PropertyWidgetBase::PropertyWidgetBase(PropertyBase* prop, QWidget* parent)
|
|||||||
m_Label = new QLabel(labelText, this);
|
m_Label = new QLabel(labelText, this);
|
||||||
m_Label->setMinimumWidth(120);
|
m_Label->setMinimumWidth(120);
|
||||||
m_Layout->addWidget(m_Label);
|
m_Layout->addWidget(m_Label);
|
||||||
|
|
||||||
|
this->setEnabled(!prop->IsReadOnly());
|
||||||
}
|
}
|
||||||
PropertyWidgetBase::~PropertyWidgetBase() {
|
PropertyWidgetBase::~PropertyWidgetBase() {
|
||||||
m_Connection.disconnect();
|
m_Connection.disconnect();
|
||||||
@@ -150,7 +152,7 @@ DoublePropertyWidget::DoublePropertyWidget(Property<double>* prop, QWidget* pare
|
|||||||
m_Edit->setValue(prop->Get());
|
m_Edit->setValue(prop->Get());
|
||||||
m_Layout->addWidget(m_Edit, 1);
|
m_Layout->addWidget(m_Edit, 1);
|
||||||
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set(val); });
|
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set(val); });
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<double>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<double>::Updated, [this](){
|
||||||
m_Edit->setValue(m_Prop->Get());
|
m_Edit->setValue(m_Prop->Get());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -168,7 +170,7 @@ FloatPropertyWidget::FloatPropertyWidget(Property<float>* prop, QWidget* parent)
|
|||||||
m_Edit->setValue(prop->Get());
|
m_Edit->setValue(prop->Get());
|
||||||
m_Layout->addWidget(m_Edit, 1);
|
m_Layout->addWidget(m_Edit, 1);
|
||||||
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set((float)val); });
|
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set((float)val); });
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<float>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<float>::Updated, [this](){
|
||||||
m_Edit->setValue((double)m_Prop->Get());
|
m_Edit->setValue((double)m_Prop->Get());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -187,7 +189,7 @@ IntPropertyWidget::IntPropertyWidget(Property<int>* prop, QWidget* parent)
|
|||||||
m_Edit->setValue(prop->Get());
|
m_Edit->setValue(prop->Get());
|
||||||
m_Layout->addWidget(m_Edit, 1);
|
m_Layout->addWidget(m_Edit, 1);
|
||||||
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set((int)val); });
|
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set((int)val); });
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<int>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<int>::Updated, [this](){
|
||||||
m_Edit->setValue((double)m_Prop->Get());
|
m_Edit->setValue((double)m_Prop->Get());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -198,7 +200,7 @@ BoolPropertyWidget::BoolPropertyWidget(Property<bool>* prop, QWidget* parent)
|
|||||||
m_CheckBox->setChecked(prop->Get());
|
m_CheckBox->setChecked(prop->Get());
|
||||||
m_Layout->addWidget(m_CheckBox, 1);
|
m_Layout->addWidget(m_CheckBox, 1);
|
||||||
connect(m_CheckBox, &QCheckBox::toggled, [this](bool val){ if (m_Prop->Get() != val) m_Prop->Set(val); });
|
connect(m_CheckBox, &QCheckBox::toggled, [this](bool val){ if (m_Prop->Get() != val) m_Prop->Set(val); });
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<bool>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<bool>::Updated, [this](){
|
||||||
if (m_CheckBox->isChecked() != m_Prop->Get()) {
|
if (m_CheckBox->isChecked() != m_Prop->Get()) {
|
||||||
QSignalBlocker blocker(m_CheckBox);
|
QSignalBlocker blocker(m_CheckBox);
|
||||||
m_CheckBox->setChecked(m_Prop->Get());
|
m_CheckBox->setChecked(m_Prop->Get());
|
||||||
@@ -222,7 +224,7 @@ RangePropertyWidget::RangePropertyWidget(Property<double>* prop, QWidget* parent
|
|||||||
connect(m_Slider, &QSlider::valueChanged, this, &RangePropertyWidget::onSliderChanged);
|
connect(m_Slider, &QSlider::valueChanged, this, &RangePropertyWidget::onSliderChanged);
|
||||||
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set(val); });
|
connect(m_Edit, &UnitLineEdit::valueManualChanged, [this](double val){ m_Prop->Set(val); });
|
||||||
|
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<double>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<double>::Updated, [this](){
|
||||||
this->updateUi();
|
this->updateUi();
|
||||||
});
|
});
|
||||||
updateUi();
|
updateUi();
|
||||||
@@ -252,7 +254,7 @@ ColorPropertyWidget::ColorPropertyWidget(Property<Vector3d>* prop, QWidget* pare
|
|||||||
m_Layout->addWidget(m_Button, 0, ::Qt::AlignRight);
|
m_Layout->addWidget(m_Button, 0, ::Qt::AlignRight);
|
||||||
|
|
||||||
connect(m_Button, &QPushButton::clicked, this, &ColorPropertyWidget::onClicked);
|
connect(m_Button, &QPushButton::clicked, this, &ColorPropertyWidget::onClicked);
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<Vector3d>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<Vector3d>::Updated, [this](){
|
||||||
this->updateButtonColor();
|
this->updateButtonColor();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -286,7 +288,7 @@ StringPropertyWidget::StringPropertyWidget(Property<std::string>* prop, QWidget*
|
|||||||
std::string val = m_LineEdit->text().toStdString();
|
std::string val = m_LineEdit->text().toStdString();
|
||||||
if (m_Prop->Get() != val) m_Prop->Set(val);
|
if (m_Prop->Get() != val) m_Prop->Set(val);
|
||||||
});
|
});
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<std::string>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<std::string>::Updated, [this](){
|
||||||
if (m_LineEdit->text().toStdString() != m_Prop->Get()) {
|
if (m_LineEdit->text().toStdString() != m_Prop->Get()) {
|
||||||
QSignalBlocker blocker(m_LineEdit);
|
QSignalBlocker blocker(m_LineEdit);
|
||||||
m_LineEdit->setText(QString::fromStdString(m_Prop->Get()));
|
m_LineEdit->setText(QString::fromStdString(m_Prop->Get()));
|
||||||
@@ -334,7 +336,7 @@ public:
|
|||||||
p->Set(index);
|
p->Set(index);
|
||||||
});
|
});
|
||||||
// Store connection in base m_Connection so it's auto-disconnected on destruction.
|
// Store connection in base m_Connection so it's auto-disconnected on destruction.
|
||||||
m_Connection = uLib::Object::connect(p, &Property<int>::PropertyChanged, [this, p](){
|
m_Connection = uLib::Object::connect(p, &Property<int>::Updated, [this, p](){
|
||||||
if (m_Combo->currentIndex() != p->Get()) {
|
if (m_Combo->currentIndex() != p->Get()) {
|
||||||
QSignalBlocker blocker(m_Combo);
|
QSignalBlocker blocker(m_Combo);
|
||||||
m_Combo->setCurrentIndex(p->Get());
|
m_Combo->setCurrentIndex(p->Get());
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ public:
|
|||||||
if (!prefSuffix.isEmpty()) {
|
if (!prefSuffix.isEmpty()) {
|
||||||
m_Edits[i]->setUnits(prefSuffix, factor);
|
m_Edits[i]->setUnits(prefSuffix, factor);
|
||||||
}
|
}
|
||||||
|
m_Edits[i]->setEnabled(!prop->IsReadOnly());
|
||||||
m_Layout->addWidget(m_Edits[i], 1);
|
m_Layout->addWidget(m_Edits[i], 1);
|
||||||
|
|
||||||
connect(m_Edits[i], &UnitLineEdit::valueManualChanged, [this, i](double val){
|
connect(m_Edits[i], &UnitLineEdit::valueManualChanged, [this, i](double val){
|
||||||
@@ -124,7 +125,7 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
updateEdits();
|
updateEdits();
|
||||||
m_Connection = uLib::Object::connect(m_Prop, &Property<VecT>::PropertyChanged, [this](){
|
m_Connection = uLib::Object::connect(m_Prop, &Property<VecT>::Updated, [this](){
|
||||||
updateEdits();
|
updateEdits();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
84
docs/archives.md
Normal file
84
docs/archives.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# Serialization and Archives Internals
|
||||||
|
|
||||||
|
This document explains the internal design of the `uLib` serialization system, which is built on top of **Boost.Serialization**. It provides custom archive implementations for various formats (XML, Text, Logging) and introduces **Human Readable Pairs (HRP)** for metadata-rich serialization.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
The `uLib` archive system extends the standard `boost::archive` templates to add domain-specific features. The main components are:
|
||||||
|
|
||||||
|
1. **Custom Interface Layer**: Extends the default Boost archive API with additional operators and utilities.
|
||||||
|
2. **Specialized Archive Implementations**: Specialized classes for XML, Text, and Logging.
|
||||||
|
3. **HRP Support**: First-class support for `hrp` (Human Readable Pair) wrappers, which carry units, ranges, and descriptions.
|
||||||
|
4. **Static Registration System**: Macros and explicit instantiations to handle polymorphic types and compilation isolation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Custom Interface Layer
|
||||||
|
|
||||||
|
All `uLib` archives use a custom interface defined in `Archives.h` via `uLib_interface_iarchive` and `uLib_interface_oarchive`. These templates add several key features:
|
||||||
|
|
||||||
|
| Feature | Operator/Method | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| **Mapping Operator** | `operator==` | Aliased to `operator&` (Boost's standard mapping operator). |
|
||||||
|
| **Trace Operator** | `operator!=` | Used for trace/debug output of strings during serialization. |
|
||||||
|
| **Type Registration** | `register_type<T>()` | Registers a class type with the archive's internal serializer map. |
|
||||||
|
| **Standard IO** | `operator<<` / `operator>>` | Standard redirect for saving and loading. |
|
||||||
|
|
||||||
|
These interfaces are applied to the archives using template specialization of `boost::archive::detail::interface_iarchive` and `interface_oarchive`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Archive Variants
|
||||||
|
|
||||||
|
### XML Archives (`xml_iarchive`, `xml_oarchive`)
|
||||||
|
These inherit from `boost::archive::xml_iarchive_impl` and `xml_oarchive_impl`.
|
||||||
|
- **Internals**: They override `load_override` and `save_override` to handle `boost::serialization::hrp<T>` specifically.
|
||||||
|
- **XML Mapping**: When saving an `hrp`, it uses `save_start(name)` and `save_end(name)` to wrap the value in a named XML tag.
|
||||||
|
|
||||||
|
### Text Archives (`text_iarchive`, `text_oarchive`)
|
||||||
|
Standard text-based archives used for compact serialization. They use `StringReader` to consume decorative text markers during loading.
|
||||||
|
|
||||||
|
### Human Readable Text (`hrt_iarchive`, `hrt_oarchive`)
|
||||||
|
These are "naked" text archives that suppress most of Boost's internal metadata (object IDs, class IDs, versions).
|
||||||
|
- **Goal**: Produce text output that is easy for humans to read and edit.
|
||||||
|
- **Internals**: All overrides for Boost internal types (like `object_id_type`, `version_type`, etc.) are implemented as no-ops.
|
||||||
|
|
||||||
|
### Log Archive (`log_archive`)
|
||||||
|
An XML-based output archive specifically for debug logging.
|
||||||
|
- **Internals**: It forces every object into a Name-Value Pair (NVP) even if not provided by the user, and strips all technical metadata to keep the logs clean.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HRP (Human Readable Pair) Integration
|
||||||
|
|
||||||
|
`hrp` is a core `uLib` wrapper (defined in `Serializable.h`) that extends Boost's `nvp`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Example of HRP usage
|
||||||
|
ar & HRP2("Energy", m_energy, "MeV").range(0, 100);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Internal Handling in Archives
|
||||||
|
Archives in `Archives.h` provide specific `save_override`/`load_override` for `hrp<T>`:
|
||||||
|
- **XML**: Maps the `name()` to an XML tag.
|
||||||
|
- **HRT**: Formats as `name: value [units]\n`.
|
||||||
|
- **Log**: Converts it to a standard Boost `nvp` for consistent XML logging.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Registration and Polymorphism
|
||||||
|
|
||||||
|
### Registration Macro
|
||||||
|
The `ULIB_SERIALIZATION_REGISTER_ARCHIVE(Archive)` macro is crucial for polymorphic serialization. It instantiates the necessary template machinery to link the custom `Archive` type with any `Serializable` class exported via `BOOST_CLASS_EXPORT`.
|
||||||
|
|
||||||
|
### Explicit Instantiation
|
||||||
|
To reduce compilation times and provide a single point of failure for link-time issues, `uLib` uses explicit instantiations in `src/Core/Archives.cpp`. This file includes the `.ipp` implementation files from Boost and instantiates the `archive_serializer_map` and implementation classes for all `uLib` archive types.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Utility: StringReader
|
||||||
|
The `StringReader` utility is used internally by text-based archives to parse and skip literals. For example:
|
||||||
|
- When loading a string literal from a text archive, `StringReader` consumes whitespace and ensures the stream matches the expected string, failing if there is a mismatch.
|
||||||
|
- This is vital for maintaining the structure of human-readable formats.
|
||||||
11
docs/geant_integration.md
Normal file
11
docs/geant_integration.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Geant integration
|
||||||
|
|
||||||
|
Geant4 integration in uLib is done through the `HEP/Geant` module.
|
||||||
|
The module represets a set of wrapper for geant objects that are also deriving from uLib::Object so they can be used in the uLib::Object tree and visualized with the uLib::Vtk module and driven py properties.
|
||||||
|
|
||||||
|
# Geant Solid integration
|
||||||
|
|
||||||
|
Geant solid in uLib is represented by the `uLib::Geant::Solid` class and mainly BoxSolid and TessellatedSolid. The solids in Geant does not have the possibility to set properties on the fly so we need to create a new solid every time we want to change the properties of a solid. This is done by creating a new `uLib::Geant::Solid` object and setting the properties of the new solid. The new solid is then added to the `uLib::Geant::Solid` object as a child. The old solid is then removed from the `uLib::Geant::Solid` object as a child. The old solid is then deleted. However id some of the properties can be set then the library will drive the change in the solid update.
|
||||||
|
|
||||||
|
The idea is to have a mapping of solid properties that can be used in uLib for Qt representation or vtk representation. then when the property is changed the signaling will update the property in uLib and then the solid will be updated. If the Geant property can be applied to the G4 object underneath then the update will apply the change, in case it is not possible to apply the change to the G4 object underneath then the G4 element will be recreated.
|
||||||
|
In any case a updated singal is emitted and the related element that use that solid is updated ( for instance the scene ).
|
||||||
@@ -19,3 +19,76 @@ The vtkHandlerWidget should handle the transformation of the puppet internal Con
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ACTIVATE PROPERTIES
|
||||||
|
|
||||||
|
ULIB_ACTIVATE_PROPERTIES must run after all member initialization, with the vtable pointing to the most-derived type. This is why it has to be in each constructor — in C++, virtual dispatch only works correctly after a class's vtable is installed, which happens at the start of each level's constructor body.
|
||||||
|
|
||||||
|
### Option 1 — End-of-class macro (no constructor boilerplate)
|
||||||
|
Declare a private member activator as the last member of the class. Its constructor runs after all other members, and at that point the vtable is already Derived's:
|
||||||
|
|
||||||
|
|
||||||
|
// In Property.h, add alongside ULIB_ACTIVATE_PROPERTIES:
|
||||||
|
#define ULIB_DECLARE_PROPERTIES(SelfType) \
|
||||||
|
private: \
|
||||||
|
struct _PropActivator { \
|
||||||
|
_PropActivator(SelfType* self) { \
|
||||||
|
uLib::Archive::property_register_archive ar(self); \
|
||||||
|
ar & *self; \
|
||||||
|
} \
|
||||||
|
} _prop_activator{this};
|
||||||
|
Usage in ContainerBox.h — place it just before the closing brace:
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerBox : public TRS {
|
||||||
|
public:
|
||||||
|
// ... all constructors, no more ULIB_ACTIVATE_PROPERTIES(*this)
|
||||||
|
|
||||||
|
ULIB_DECLARE_PROPERTIES(ContainerBox) // ← replaces all 3 constructor calls
|
||||||
|
};
|
||||||
|
Tradeoff: Works perfectly for single-level classes. For hierarchies where multiple levels use the macro, RegisterDynamicProperty must deduplicate by name (skip if already registered). Requires one line per class in the class body, but zero lines in constructors.
|
||||||
|
|
||||||
|
### Option 2 — Lazy init via virtual InitProperties() in Object
|
||||||
|
Modify Object to call a virtual hook on first GetProperties():
|
||||||
|
|
||||||
|
|
||||||
|
// In Object.h:
|
||||||
|
class Object {
|
||||||
|
protected:
|
||||||
|
virtual void InitProperties() {} // override in derived
|
||||||
|
public:
|
||||||
|
const std::vector<PropertyBase*>& GetProperties() const {
|
||||||
|
if (!m_propertiesInitialized) {
|
||||||
|
const_cast<Object*>(this)->m_propertiesInitialized = true;
|
||||||
|
const_cast<Object*>(this)->InitProperties();
|
||||||
|
}
|
||||||
|
return m_properties;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Then a CRTP base handles the rest without any macro:
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
class PropertyObject : public Object {
|
||||||
|
protected:
|
||||||
|
void InitProperties() override {
|
||||||
|
uLib::Archive::property_register_archive ar(this);
|
||||||
|
ar & *static_cast<Derived*>(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Usage — just change the base class:
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerBox : public PropertyObject<ContainerBox>, public TRS { ... };
|
||||||
|
// Nothing else needed — properties activated on first GetProperties() call
|
||||||
|
Tradeoff: Most "automatic" — pure inheritance, no constructor or class-body macros. But requires modifying Object (adding m_propertiesInitialized flag + virtual hook), and lazy init means properties aren't available until first access. Also doesn't work well with multiple inheritance (which TRS likely involves).
|
||||||
|
|
||||||
|
Option 3 — CRTP doesn't work from the base constructor
|
||||||
|
Just to be explicit: a CRTP base that calls ULIB_ACTIVATE_PROPERTIES in its own constructor won't work, because when PropertyObject<Derived>'s constructor runs, the vtable is PropertyObject<Derived>'s — Derived::serialize() hasn't been installed yet. So ar & *self calls Object::serialize() (a no-op).
|
||||||
|
|
||||||
|
Recommendation
|
||||||
|
Option 1 is the least invasive and safest. Add deduplication to RegisterDynamicProperty in Object.cpp to guard against re-registration when hierarchies stack activators, then replace every ULIB_ACTIVATE_PROPERTIES(*this) in constructors with a single ULIB_DECLARE_PROPERTIES(ClassName) at the end of the class body.
|
||||||
|
|
||||||
|
Option 2 is cleaner to use but requires changing the Object interface and has the lazy-init semantic change — only worth it if you want zero-touch activation across the entire framework.
|
||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include <boost/archive/detail/basic_pointer_iserializer.hpp>
|
#include <boost/archive/detail/basic_pointer_iserializer.hpp>
|
||||||
#include <boost/archive/detail/basic_pointer_oserializer.hpp>
|
#include <boost/archive/detail/basic_pointer_oserializer.hpp>
|
||||||
|
#include <boost/archive/text_oarchive.hpp>
|
||||||
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <boost/archive/text_iarchive.hpp>
|
#include <boost/archive/text_iarchive.hpp>
|
||||||
@@ -59,6 +61,8 @@ class xml_iarchive;
|
|||||||
class xml_oarchive;
|
class xml_oarchive;
|
||||||
class text_iarchive;
|
class text_iarchive;
|
||||||
class text_oarchive;
|
class text_oarchive;
|
||||||
|
class hrt_iarchive;
|
||||||
|
class hrt_oarchive;
|
||||||
class log_archive;
|
class log_archive;
|
||||||
|
|
||||||
} // namespace Archive
|
} // namespace Archive
|
||||||
@@ -150,7 +154,7 @@ public:
|
|||||||
Archive *This() { return static_cast<Archive *>(this); }
|
Archive *This() { return static_cast<Archive *>(this); }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
const basic_pointer_iserializer *register_type(T * = NULL) {
|
const basic_pointer_iserializer *register_type(T * = nullptr) {
|
||||||
const basic_pointer_iserializer &bpis = boost::serialization::singleton<
|
const basic_pointer_iserializer &bpis = boost::serialization::singleton<
|
||||||
pointer_iserializer<Archive, T>>::get_const_instance();
|
pointer_iserializer<Archive, T>>::get_const_instance();
|
||||||
this->This()->register_basic_serializer(bpis.get_basic_serializer());
|
this->This()->register_basic_serializer(bpis.get_basic_serializer());
|
||||||
@@ -161,15 +165,36 @@ public:
|
|||||||
return *this->This();
|
return *this->This();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Archive &operator>>(const boost::serialization::nvp<T> &t) {
|
||||||
|
this->This()->load_override(t);
|
||||||
|
return *this->This();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Archive &operator>>(const boost::serialization::hrp<T> &t) {
|
||||||
|
this->This()->load_override(const_cast<boost::serialization::hrp<T> &>(t));
|
||||||
|
return *this->This();
|
||||||
|
}
|
||||||
|
|
||||||
// the & operator
|
// the & operator
|
||||||
template <class T> Archive &operator&(T &t) { return *(this->This()) >> t; }
|
template <class T> Archive &operator&(T &t) { return *(this->This()) >> t; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Archive &operator&(const boost::serialization::nvp<T> &t) {
|
||||||
|
return *(this->This()) >> t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Archive &operator&(const boost::serialization::hrp<T> &t) {
|
||||||
|
return *(this->This()) >> t;
|
||||||
|
}
|
||||||
|
|
||||||
// the == operator
|
// the == operator
|
||||||
template <class T> Archive &operator==(T &t) { return this->operator&(t); }
|
template <class T> Archive &operator==(T &t) { return this->operator&(t); }
|
||||||
|
|
||||||
// the != operator for human readable access
|
// the != operator for human readable access
|
||||||
template <class T> Archive &operator!=(T &t) {
|
template <class T> Archive &operator!=(T &t) {
|
||||||
std::cerr << std::flush << "cauch string: " << t << "\n"; // REMOVE THIS !
|
|
||||||
return *this->This();
|
return *this->This();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -191,7 +216,7 @@ public:
|
|||||||
Archive *This() { return static_cast<Archive *>(this); }
|
Archive *This() { return static_cast<Archive *>(this); }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
const basic_pointer_oserializer *register_type(const T * = NULL) {
|
const basic_pointer_oserializer *register_type(const T * = nullptr) {
|
||||||
const basic_pointer_oserializer &bpos = boost::serialization::singleton<
|
const basic_pointer_oserializer &bpos = boost::serialization::singleton<
|
||||||
pointer_oserializer<Archive, T>>::get_const_instance();
|
pointer_oserializer<Archive, T>>::get_const_instance();
|
||||||
this->This()->register_basic_serializer(bpos.get_basic_serializer());
|
this->This()->register_basic_serializer(bpos.get_basic_serializer());
|
||||||
@@ -215,7 +240,6 @@ public:
|
|||||||
|
|
||||||
// the != operator for human readable access
|
// the != operator for human readable access
|
||||||
template <class T> Archive &operator!=(T &t) {
|
template <class T> Archive &operator!=(T &t) {
|
||||||
std::cerr << std::flush << "cauch string: " << t << "\n"; // REMOVE THIS !
|
|
||||||
return *this->This();
|
return *this->This();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -240,23 +264,22 @@ template <>
|
|||||||
class interface_oarchive<uLib::Archive::text_oarchive>
|
class interface_oarchive<uLib::Archive::text_oarchive>
|
||||||
: public uLib_interface_oarchive<uLib::Archive::text_oarchive> {};
|
: public uLib_interface_oarchive<uLib::Archive::text_oarchive> {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class interface_iarchive<uLib::Archive::hrt_iarchive>
|
||||||
|
: public uLib_interface_iarchive<uLib::Archive::hrt_iarchive> {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class interface_oarchive<uLib::Archive::hrt_oarchive>
|
||||||
|
: public uLib_interface_oarchive<uLib::Archive::hrt_oarchive> {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class interface_iarchive<uLib::Archive::log_archive>
|
||||||
|
: public uLib_interface_iarchive<uLib::Archive::log_archive> {};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class interface_oarchive<uLib::Archive::log_archive>
|
class interface_oarchive<uLib::Archive::log_archive>
|
||||||
: public uLib_interface_oarchive<uLib::Archive::log_archive> {};
|
: public uLib_interface_oarchive<uLib::Archive::log_archive> {};
|
||||||
|
|
||||||
//// Veritical repetition macro // FINIRE !!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
// #define _DECL_INTERFACE_ARCHIVE_V(vz,vn,vdata) \
|
|
||||||
// template <class TypeSeq> \
|
|
||||||
// struct inherit_nofold<TypeSeq,BOOST_PP_INC(vn)> : \
|
|
||||||
// BOOST_PP_REPEAT(BOOST_PP_INC(vn),_INERIT_NOFOLD_H,~) \
|
|
||||||
// {};
|
|
||||||
|
|
||||||
//// Multiple size declaration //
|
|
||||||
// BOOST_PP_REPEAT(ULIB_CFG_MPL_INERIT_NOFOLD_MAXSIZE,_INERIT_NOFOLD_V,~)
|
|
||||||
|
|
||||||
// #undef _INERIT_NOFOLD_H
|
|
||||||
// #undef _INERIT_NOFOLD_V
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace archive
|
} // namespace archive
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
@@ -275,36 +298,6 @@ class interface_oarchive<uLib::Archive::log_archive>
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace archive {
|
namespace archive {
|
||||||
|
|
||||||
// template<class Archive>
|
|
||||||
// inline void load_const_override(Archive & ar, const char *t ){
|
|
||||||
// typedef typename mpl::identity<detail::load_non_pointer_type<Archive>
|
|
||||||
// >::type typex; typex::invoke(ar, t);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// template<class Archive, class T>
|
|
||||||
// inline void load(Archive & ar, T &t){
|
|
||||||
// // if this assertion trips. It means we're trying to load a
|
|
||||||
// // const object with a compiler that doesn't have correct
|
|
||||||
// // funtion template ordering. On other compilers, this is
|
|
||||||
// // handled below.
|
|
||||||
// // detail::check_const_loading< T >();
|
|
||||||
// typedef
|
|
||||||
// BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer< T >,
|
|
||||||
// mpl::identity<detail::load_pointer_type<Archive> >
|
|
||||||
// ,//else
|
|
||||||
// BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array< T >,
|
|
||||||
// mpl::identity<detail::load_array_type<Archive> >
|
|
||||||
// ,//else
|
|
||||||
// BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum< T >,
|
|
||||||
// mpl::identity<detail::load_enum_type<Archive> >
|
|
||||||
// ,//else
|
|
||||||
// mpl::identity<detail::load_non_pointer_type<Archive> >
|
|
||||||
// >
|
|
||||||
// >
|
|
||||||
// >::type typex;
|
|
||||||
// typex::invoke(ar, t);
|
|
||||||
// }
|
|
||||||
|
|
||||||
} // namespace archive
|
} // namespace archive
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
@@ -312,40 +305,38 @@ namespace uLib {
|
|||||||
|
|
||||||
namespace Archive {
|
namespace Archive {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// POLYMORPHIC //
|
|
||||||
|
|
||||||
// class polymorphic_iarchive :
|
|
||||||
// public boost::archive::polymorphic_iarchive {
|
|
||||||
|
|
||||||
// public:
|
|
||||||
// void load_override(const char *t, BOOST_PFTO int)
|
|
||||||
// {
|
|
||||||
// boost::archive::load_const_override(* this->This(),
|
|
||||||
// const_cast<char*>(t));
|
|
||||||
// }
|
|
||||||
|
|
||||||
//};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// XML //
|
// XML //
|
||||||
|
|
||||||
|
// ULIB_SERIALIZATION_VERSION should be get from the build system
|
||||||
|
#ifndef ULIB_SERIALIZATION_VERSION
|
||||||
|
#define ULIB_SERIALIZATION_VERSION "0.0"
|
||||||
|
#endif
|
||||||
|
|
||||||
class xml_iarchive : public boost::archive::xml_iarchive_impl<xml_iarchive> {
|
class xml_iarchive : public boost::archive::xml_iarchive_impl<xml_iarchive> {
|
||||||
typedef xml_iarchive Archive;
|
typedef xml_iarchive Archive;
|
||||||
typedef boost::archive::xml_iarchive_impl<Archive> base;
|
typedef boost::archive::xml_iarchive_impl<Archive> base;
|
||||||
|
|
||||||
|
unsigned int m_flags;
|
||||||
|
|
||||||
// give serialization implementation access to this class
|
// give serialization implementation access to this class
|
||||||
friend class boost::archive::detail::interface_iarchive<Archive>;
|
friend class boost::archive::detail::interface_iarchive<Archive>;
|
||||||
friend class boost::archive::basic_xml_iarchive<Archive>;
|
friend class boost::archive::basic_xml_iarchive<Archive>;
|
||||||
friend class boost::archive::load_access;
|
friend class boost::archive::load_access;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
xml_iarchive(std::istream &is, unsigned int flags = 0)
|
xml_iarchive(std::istream &is, unsigned int flags = 0)
|
||||||
: xml_iarchive_impl<xml_iarchive>(is, flags) {}
|
: boost::archive::xml_iarchive_impl<xml_iarchive>(
|
||||||
|
is, flags | boost::archive::no_header), m_flags(flags) {
|
||||||
|
if (0 == (flags & boost::archive::no_header)) {
|
||||||
|
std::string line;
|
||||||
|
std::getline(is, line); // <?xml ... ?>
|
||||||
|
std::getline(is, line); // <!DOCTYPE ...>
|
||||||
|
std::getline(is, line); // <ulib_serialization ...>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
using basic_xml_iarchive::load_override;
|
using basic_xml_iarchive::load_override;
|
||||||
|
|
||||||
@@ -369,17 +360,13 @@ public:
|
|||||||
using base::load_override;
|
using base::load_override;
|
||||||
|
|
||||||
void load_override(const char *str) {
|
void load_override(const char *str) {
|
||||||
// StringReader sr(basic_text_iprimitive::is);
|
// StringReader sr(basic_text_iprimitive::is);
|
||||||
// sr >> str;
|
// sr >> str;
|
||||||
}
|
}
|
||||||
|
|
||||||
~xml_iarchive() {};
|
virtual ~xml_iarchive() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// typedef boost::archive::detail::polymorphic_iarchive_route<
|
|
||||||
// boost::archive::xml_iarchive_impl<xml_iarchive>
|
|
||||||
//> polymorphic_xml_iarchive;
|
|
||||||
|
|
||||||
template <class ArchiveImpl>
|
template <class ArchiveImpl>
|
||||||
struct polymorphic_iarchive_route
|
struct polymorphic_iarchive_route
|
||||||
: boost::archive::detail::polymorphic_iarchive_route<ArchiveImpl> {
|
: boost::archive::detail::polymorphic_iarchive_route<ArchiveImpl> {
|
||||||
@@ -389,31 +376,39 @@ struct polymorphic_iarchive_route
|
|||||||
class polymorphic_xml_iarchive
|
class polymorphic_xml_iarchive
|
||||||
: public polymorphic_iarchive_route<
|
: public polymorphic_iarchive_route<
|
||||||
boost::archive::xml_iarchive_impl<xml_iarchive>> {
|
boost::archive::xml_iarchive_impl<xml_iarchive>> {
|
||||||
// give serialization implementation access to this class
|
|
||||||
// friend class boost::archive::detail::interface_iarchive<Archive>;
|
|
||||||
// friend class boost::archive::basic_xml_iarchive<Archive>;
|
|
||||||
// friend class boost::archive::load_access;
|
|
||||||
public:
|
public:
|
||||||
virtual void load_override(const char *str) { ; }
|
virtual void load_override(const char *str) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class xml_oarchive : public boost::archive::xml_oarchive_impl<xml_oarchive> {
|
class xml_oarchive : public boost::archive::xml_oarchive_impl<xml_oarchive> {
|
||||||
typedef xml_oarchive Archive;
|
typedef xml_oarchive Archive;
|
||||||
typedef boost::archive::xml_oarchive_impl<Archive> base;
|
typedef boost::archive::xml_oarchive_impl<Archive> base;
|
||||||
|
|
||||||
|
unsigned int m_flags;
|
||||||
|
|
||||||
// give serialization implementation access to this class
|
// give serialization implementation access to this class
|
||||||
friend class boost::archive::detail::interface_oarchive<Archive>;
|
friend class boost::archive::detail::interface_oarchive<Archive>;
|
||||||
friend class boost::archive::basic_xml_oarchive<Archive>;
|
friend class boost::archive::basic_xml_oarchive<Archive>;
|
||||||
friend class boost::archive::save_access;
|
friend class boost::archive::save_access;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
xml_oarchive(std::ostream &os, unsigned int flags = 0)
|
xml_oarchive(std::ostream &os, unsigned int flags = 0)
|
||||||
: boost::archive::xml_oarchive_impl<xml_oarchive>(os, flags) {}
|
: boost::archive::xml_oarchive_impl<xml_oarchive>(
|
||||||
|
os, flags | boost::archive::no_header), m_flags(flags) {
|
||||||
|
if (0 == (flags & boost::archive::no_header)) {
|
||||||
|
this->This()->put(
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n");
|
||||||
|
this->This()->put("<!DOCTYPE ulib_serialization>\n");
|
||||||
|
this->This()->put("<ulib_serialization signature=\"serialization::archive\" ");
|
||||||
|
this->write_attribute("version", (const char *)ULIB_SERIALIZATION_VERSION);
|
||||||
|
this->This()->put(">\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// example of implementing save_override for const char* //
|
virtual ~xml_oarchive() {
|
||||||
// void save_override(const char *t, int) {
|
if (0 == (m_flags & boost::archive::no_header)) {
|
||||||
// std::cout << "found char: " << t << "\n";
|
this->This()->put("</ulib_serialization>\n");
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
using basic_xml_oarchive::save_override;
|
using basic_xml_oarchive::save_override;
|
||||||
|
|
||||||
@@ -433,10 +428,8 @@ public:
|
|||||||
|
|
||||||
void save_override(const char *str) {
|
void save_override(const char *str) {
|
||||||
// Do not save any human decoration string //
|
// Do not save any human decoration string //
|
||||||
// basic_text_oprimitive::save(str);
|
// basic_text_oprimitive::save(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
~xml_oarchive() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// typedef boost::archive::detail::polymorphic_oarchive_route<
|
// typedef boost::archive::detail::polymorphic_oarchive_route<
|
||||||
@@ -471,15 +464,11 @@ public:
|
|||||||
sr >> str;
|
sr >> str;
|
||||||
}
|
}
|
||||||
|
|
||||||
~text_iarchive() {};
|
virtual ~text_iarchive() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef text_iarchive naked_text_iarchive;
|
typedef text_iarchive naked_text_iarchive;
|
||||||
|
|
||||||
// typedef boost::archive::detail::polymorphic_iarchive_route<
|
|
||||||
// naked_text_iarchive
|
|
||||||
//> polymorphic_text_iarchive;
|
|
||||||
|
|
||||||
class text_oarchive : public boost::archive::text_oarchive_impl<text_oarchive> {
|
class text_oarchive : public boost::archive::text_oarchive_impl<text_oarchive> {
|
||||||
typedef text_oarchive Archive;
|
typedef text_oarchive Archive;
|
||||||
typedef boost::archive::text_oarchive_impl<Archive> base;
|
typedef boost::archive::text_oarchive_impl<Archive> base;
|
||||||
@@ -497,13 +486,9 @@ public:
|
|||||||
|
|
||||||
void save_override(const char *str) { basic_text_oprimitive::save(str); }
|
void save_override(const char *str) { basic_text_oprimitive::save(str); }
|
||||||
|
|
||||||
~text_oarchive() {}
|
virtual ~text_oarchive() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// typedef boost::archive::detail::polymorphic_oarchive_route<
|
|
||||||
// boost::archive::text_oarchive_impl<text_oarchive>
|
|
||||||
//> polymorphic_text_oarchive;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -540,7 +525,7 @@ public:
|
|||||||
sr >> str;
|
sr >> str;
|
||||||
}
|
}
|
||||||
|
|
||||||
~hrt_iarchive() {};
|
virtual ~hrt_iarchive() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class hrt_oarchive : public boost::archive::text_oarchive_impl<hrt_oarchive> {
|
class hrt_oarchive : public boost::archive::text_oarchive_impl<hrt_oarchive> {
|
||||||
@@ -576,7 +561,7 @@ public:
|
|||||||
*this << "\n";
|
*this << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
~hrt_oarchive() {}
|
virtual ~hrt_oarchive() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -605,17 +590,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T> void save_override(const T &t) {
|
template <class T> void save_override(const T &t) {
|
||||||
base::save_override(boost::serialization::make_nvp(NULL, t));
|
base::save_override(boost::serialization::make_nvp(nullptr, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// activate this if you want to trap non nvp objects //
|
|
||||||
// template<class T>
|
|
||||||
// void save_override(T & t)
|
|
||||||
// {
|
|
||||||
// BOOST_MPL_ASSERT((boost::serialization::is_wrapper< T >));
|
|
||||||
// // this->detail_common_oarchive::save_override(t);
|
|
||||||
// }
|
|
||||||
|
|
||||||
template <class T> void save_override(const boost::serialization::nvp<T> &t) {
|
template <class T> void save_override(const boost::serialization::nvp<T> &t) {
|
||||||
base::save_override(t);
|
base::save_override(t);
|
||||||
}
|
}
|
||||||
@@ -640,11 +617,9 @@ public:
|
|||||||
log_archive(std::ostream &os, unsigned int flags = 0)
|
log_archive(std::ostream &os, unsigned int flags = 0)
|
||||||
: boost::archive::xml_oarchive_impl<log_archive>(
|
: boost::archive::xml_oarchive_impl<log_archive>(
|
||||||
os, flags | boost::archive::no_header) {}
|
os, flags | boost::archive::no_header) {}
|
||||||
};
|
|
||||||
|
|
||||||
// typedef boost::archive::detail::polymorphic_oarchive_route<
|
virtual ~log_archive() {}
|
||||||
// boost::archive::xml_oarchive_impl<log_archive>
|
};
|
||||||
//> polymorphic_log_archive;
|
|
||||||
|
|
||||||
} // namespace Archive
|
} // namespace Archive
|
||||||
|
|
||||||
@@ -658,10 +633,4 @@ ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::hrt_iarchive)
|
|||||||
ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::hrt_oarchive)
|
ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::hrt_oarchive)
|
||||||
ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::log_archive)
|
ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::log_archive)
|
||||||
|
|
||||||
// ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_xml_iarchive)
|
|
||||||
// ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_xml_oarchive)
|
|
||||||
// ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_text_iarchive)
|
|
||||||
// ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_text_oarchive)
|
|
||||||
// ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_log_archive)
|
|
||||||
|
|
||||||
#endif // U_CORE_ARCHIVES_H
|
#endif // U_CORE_ARCHIVES_H
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ if(USE_CUDA)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${libname} ${LIBRARIES})
|
target_link_libraries(${libname} ${LIBRARIES})
|
||||||
|
target_compile_definitions(${libname} PUBLIC ULIB_SERIALIZATION_VERSION="${PROJECT_VERSION}")
|
||||||
|
|
||||||
install(TARGETS ${libname}
|
install(TARGETS ${libname}
|
||||||
EXPORT "uLibTargets"
|
EXPORT "uLibTargets"
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ void Object::RegisterDynamicProperty(PropertyBase* prop) {
|
|||||||
if (prop) {
|
if (prop) {
|
||||||
for (auto* existing : d->m_DynamicProperties) {
|
for (auto* existing : d->m_DynamicProperties) {
|
||||||
if (existing == prop) return;
|
if (existing == prop) return;
|
||||||
|
if (existing->GetQualifiedName() == prop->GetQualifiedName()) return;
|
||||||
}
|
}
|
||||||
d->m_DynamicProperties.push_back(prop);
|
d->m_DynamicProperties.push_back(prop);
|
||||||
}
|
}
|
||||||
@@ -115,6 +116,7 @@ void Object::serialize(ArchiveT &ar, const unsigned int version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Object::Updated() { ULIB_SIGNAL_EMIT(Object::Updated); }
|
void Object::Updated() { ULIB_SIGNAL_EMIT(Object::Updated); }
|
||||||
|
void Object::PropertyUpdated() { ULIB_SIGNAL_EMIT(Object::PropertyUpdated); }
|
||||||
|
|
||||||
template <class ArchiveT>
|
template <class ArchiveT>
|
||||||
void Object::save_override(ArchiveT &ar, const unsigned int version) {}
|
void Object::save_override(ArchiveT &ar, const unsigned int version) {}
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ public:
|
|||||||
Object(const Object ©);
|
Object(const Object ©);
|
||||||
virtual ~Object();
|
virtual ~Object();
|
||||||
|
|
||||||
virtual const char * GetClassName() const { return "Object"; }
|
virtual const char * GetClassName() const { return type_name(); }
|
||||||
|
virtual const char * type_name() const { return "Object"; }
|
||||||
|
|
||||||
const std::string& GetInstanceName() const;
|
const std::string& GetInstanceName() const;
|
||||||
void SetInstanceName(const std::string& name);
|
void SetInstanceName(const std::string& name);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public:
|
|||||||
ObjectsContext();
|
ObjectsContext();
|
||||||
virtual ~ObjectsContext();
|
virtual ~ObjectsContext();
|
||||||
|
|
||||||
virtual const char * GetClassName() const { return "ObjectsContext"; }
|
uLibTypeMacro(ObjectsContext, Object)
|
||||||
virtual ObjectsContext* GetChildren() override { return this; }
|
virtual ObjectsContext* GetChildren() override { return this; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public:
|
|||||||
virtual double GetMax() const { return 0; }
|
virtual double GetMax() const { return 0; }
|
||||||
virtual bool HasDefault() const { return false; }
|
virtual bool HasDefault() const { return false; }
|
||||||
virtual std::string GetDefaultValueAsString() const { return ""; }
|
virtual std::string GetDefaultValueAsString() const { return ""; }
|
||||||
|
virtual bool IsReadOnly() const = 0;
|
||||||
|
|
||||||
std::string GetQualifiedName() const {
|
std::string GetQualifiedName() const {
|
||||||
if (GetGroup().empty()) return GetName();
|
if (GetGroup().empty()) return GetName();
|
||||||
@@ -53,15 +54,22 @@ public:
|
|||||||
virtual void Updated() override { ULIB_SIGNAL_EMIT(PropertyBase::Updated); }
|
virtual void Updated() override { ULIB_SIGNAL_EMIT(PropertyBase::Updated); }
|
||||||
|
|
||||||
// Serialization support for different uLib archives
|
// Serialization support for different uLib archives
|
||||||
virtual void serialize(Archive::xml_oarchive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::xml_oarchive & ar, const unsigned int version) override = 0;
|
||||||
virtual void serialize(Archive::xml_iarchive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::xml_iarchive & ar, const unsigned int version) override = 0;
|
||||||
virtual void serialize(Archive::text_oarchive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::text_oarchive & ar, const unsigned int version) override = 0;
|
||||||
virtual void serialize(Archive::text_iarchive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::text_iarchive & ar, const unsigned int version) override = 0;
|
||||||
virtual void serialize(Archive::hrt_oarchive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::hrt_oarchive & ar, const unsigned int version) override = 0;
|
||||||
virtual void serialize(Archive::hrt_iarchive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::hrt_iarchive & ar, const unsigned int version) override = 0;
|
||||||
virtual void serialize(Archive::log_archive & ar, const unsigned int version) = 0;
|
virtual void serialize(Archive::log_archive & ar, const unsigned int version) override = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Template class for typed properties.
|
* @brief Template class for typed properties.
|
||||||
*/
|
*/
|
||||||
@@ -71,7 +79,7 @@ public:
|
|||||||
// PROXY: Use an existing variable as back-end storage
|
// PROXY: Use an existing variable as back-end storage
|
||||||
Property(Object* owner, const std::string& name, T* valuePtr, const std::string& units = "", const std::string& group = "")
|
Property(Object* owner, const std::string& name, T* valuePtr, const std::string& units = "", const std::string& group = "")
|
||||||
: m_owner(owner), m_name(name), m_units(units), m_group(group), m_value(valuePtr), m_own(false),
|
: m_owner(owner), m_name(name), m_units(units), m_group(group), m_value(valuePtr), m_own(false),
|
||||||
m_HasRange(false), m_HasDefault(false) {
|
m_HasRange(false), m_HasDefault(false), m_ReadOnly(false) {
|
||||||
if (m_owner) {
|
if (m_owner) {
|
||||||
m_owner->RegisterProperty(this);
|
m_owner->RegisterProperty(this);
|
||||||
}
|
}
|
||||||
@@ -80,7 +88,7 @@ public:
|
|||||||
// MANAGED: Create and own internal storage
|
// MANAGED: Create and own internal storage
|
||||||
Property(Object* owner, const std::string& name, const T& defaultValue = T(), const std::string& units = "", const std::string& group = "")
|
Property(Object* owner, const std::string& name, const T& defaultValue = T(), const std::string& units = "", const std::string& group = "")
|
||||||
: m_owner(owner), m_name(name), m_units(units), m_group(group), m_value(new T(defaultValue)), m_own(true),
|
: m_owner(owner), m_name(name), m_units(units), m_group(group), m_value(new T(defaultValue)), m_own(true),
|
||||||
m_HasRange(false), m_HasDefault(true), m_Default(defaultValue) {
|
m_HasRange(false), m_HasDefault(true), m_Default(defaultValue), m_ReadOnly(false) {
|
||||||
if (m_owner) {
|
if (m_owner) {
|
||||||
m_owner->RegisterProperty(this);
|
m_owner->RegisterProperty(this);
|
||||||
}
|
}
|
||||||
@@ -139,6 +147,9 @@ public:
|
|||||||
|
|
||||||
void SetRange(const T& min, const T& max) { m_Min = min; m_Max = max; m_HasRange = true; }
|
void SetRange(const T& min, const T& max) { m_Min = min; m_Max = max; m_HasRange = true; }
|
||||||
void SetDefault(const T& def) { m_Default = def; m_HasDefault = true; }
|
void SetDefault(const T& def) { m_Default = def; m_HasDefault = true; }
|
||||||
|
void SetReadOnly(bool ro) { m_ReadOnly = ro; }
|
||||||
|
|
||||||
|
virtual bool IsReadOnly() const override { return m_ReadOnly; }
|
||||||
|
|
||||||
virtual bool HasRange() const override { return m_HasRange; }
|
virtual bool HasRange() const override { return m_HasRange; }
|
||||||
|
|
||||||
@@ -209,6 +220,7 @@ private:
|
|||||||
T m_Max;
|
T m_Max;
|
||||||
bool m_HasDefault;
|
bool m_HasDefault;
|
||||||
T m_Default;
|
T m_Default;
|
||||||
|
bool m_ReadOnly;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,7 +233,8 @@ typedef Property<long> LongProperty;
|
|||||||
typedef Property<unsigned long> ULongProperty;
|
typedef Property<unsigned long> ULongProperty;
|
||||||
typedef Property<float> FloatProperty;
|
typedef Property<float> FloatProperty;
|
||||||
typedef Property<double> DoubleProperty;
|
typedef Property<double> DoubleProperty;
|
||||||
typedef Property<Bool_t> BoolProperty;
|
typedef Property<Bool_t> BoolProperty;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Property specialized for enumerations, providing labels for GUI representations.
|
* @brief Property specialized for enumerations, providing labels for GUI representations.
|
||||||
@@ -239,6 +252,16 @@ private:
|
|||||||
std::vector<std::string> m_Labels;
|
std::vector<std::string> m_Labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Macro to simplify property declaration within a class.
|
* @brief Macro to simplify property declaration within a class.
|
||||||
* Usage: ULIB_PROPERTY(float, Width, 1.0f)
|
* Usage: ULIB_PROPERTY(float, Width, 1.0f)
|
||||||
@@ -304,6 +327,25 @@ public:
|
|||||||
Property<T>* p = new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp<T>&>(t).value(), t.units() ? t.units() : "", GetCurrentGroup());
|
Property<T>* p = new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp<T>&>(t).value(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||||
if (t.has_range()) p->SetRange(t.min_val(), t.max_val());
|
if (t.has_range()) p->SetRange(t.min_val(), t.max_val());
|
||||||
if (t.has_default()) p->SetDefault(t.default_val());
|
if (t.has_default()) p->SetDefault(t.default_val());
|
||||||
|
p->SetReadOnly(t.is_read_only());
|
||||||
|
m_Object->RegisterDynamicProperty(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void save_override(const boost::serialization::hrp_val<T> &t) {
|
||||||
|
if (m_Object) {
|
||||||
|
// Note: hrp_val stores by value. Property usually points to existing data.
|
||||||
|
// But here we are registering properties from HRP wrappers.
|
||||||
|
// If it's hrp_val, it means it's an rvalue from a getter.
|
||||||
|
// The hrp_val wrapper itself owns the value.
|
||||||
|
// However, the property_register_archive is temporary.
|
||||||
|
// This is a bit tricky. Usually HRP(rvalue) is meant for read-only display.
|
||||||
|
// Let's use the address of the value in the wrapper, but mark it read-only.
|
||||||
|
Property<T>* p = new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp_val<T>&>(t).value(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||||
|
if (t.has_range()) p->SetRange(t.min_val(), t.max_val());
|
||||||
|
if (t.has_default()) p->SetDefault(t.default_val());
|
||||||
|
p->SetReadOnly(t.is_read_only());
|
||||||
m_Object->RegisterDynamicProperty(p);
|
m_Object->RegisterDynamicProperty(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -312,6 +354,16 @@ public:
|
|||||||
void save_override(const boost::serialization::hrp_enum<T> &t) {
|
void save_override(const boost::serialization::hrp_enum<T> &t) {
|
||||||
if (m_Object) {
|
if (m_Object) {
|
||||||
EnumProperty* p = new EnumProperty(m_Object, t.name(), (int*)&const_cast<boost::serialization::hrp_enum<T>&>(t).value(), t.labels(), t.units() ? t.units() : "", GetCurrentGroup());
|
EnumProperty* p = new EnumProperty(m_Object, t.name(), (int*)&const_cast<boost::serialization::hrp_enum<T>&>(t).value(), t.labels(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||||
|
p->SetReadOnly(t.is_read_only());
|
||||||
|
m_Object->RegisterDynamicProperty(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void save_override(const boost::serialization::hrp_enum_val<T> &t) {
|
||||||
|
if (m_Object) {
|
||||||
|
EnumProperty* p = new EnumProperty(m_Object, t.name(), (int*)&const_cast<boost::serialization::hrp_enum_val<T>&>(t).value(), t.labels(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||||
|
p->SetReadOnly(t.is_read_only());
|
||||||
m_Object->RegisterDynamicProperty(p);
|
m_Object->RegisterDynamicProperty(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,12 +404,34 @@ private:
|
|||||||
std::vector<std::string> m_GroupStack;
|
std::vector<std::string> m_GroupStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convenience macro to automatically activate and register all HRP members
|
* @brief Convenience macro to automatically activate and register all HRP members
|
||||||
* as uLib properties. Usage: ULIB_ACTIVATE_PROPERTIES(obj)
|
* as uLib properties. Usage: ULIB_ACTIVATE_PROPERTIES(obj)
|
||||||
*/
|
*/
|
||||||
#define ULIB_ACTIVATE_PROPERTIES(obj) \
|
#define ULIB_ACTIVATE_PROPERTIES(obj) \
|
||||||
{ uLib::Archive::property_register_archive _ar_tmp(&(obj)); (obj).serialize(_ar_tmp, 0); }
|
{ uLib::Archive::property_register_archive _ar_tmp(&(obj)); _ar_tmp & (obj); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declares a private member that automatically calls ULIB_ACTIVATE_PROPERTIES
|
||||||
|
* in every constructor of the class. Place this macro as the last declaration
|
||||||
|
* inside the class body (before the closing brace).
|
||||||
|
*
|
||||||
|
* Usage: ULIB_DECLARE_PROPERTIES(ClassName)
|
||||||
|
*
|
||||||
|
* This replaces per-constructor ULIB_ACTIVATE_PROPERTIES(*this) calls.
|
||||||
|
* RegisterDynamicProperty deduplicates by qualified name, so re-registration
|
||||||
|
* from inherited activators in a hierarchy is safe.
|
||||||
|
*/
|
||||||
|
#define ULIB_DECLARE_PROPERTIES(SelfType) \
|
||||||
|
private: \
|
||||||
|
struct _PropActivator { \
|
||||||
|
_PropActivator(SelfType* self) { \
|
||||||
|
uLib::Archive::property_register_archive _ar(self); \
|
||||||
|
_ar & *self; \
|
||||||
|
} \
|
||||||
|
} _prop_activator{this};
|
||||||
|
|
||||||
} // namespace Archive
|
} // namespace Archive
|
||||||
} // namespace uLib
|
} // namespace uLib
|
||||||
|
|||||||
@@ -71,15 +71,16 @@ namespace serialization {
|
|||||||
// ACCESS 2 //
|
// ACCESS 2 //
|
||||||
template <class T> struct access2 {};
|
template <class T> struct access2 {};
|
||||||
|
|
||||||
// NON FUNZIONA ... SISTEMARE !!!! // ------------------------------------------
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class hrp : public boost::serialization::wrapper_traits<hrp<T>> {
|
class hrp : public boost::serialization::wrapper_traits<hrp<T>> {
|
||||||
|
|
||||||
const char *m_name;
|
const char *m_name;
|
||||||
const char *m_units;
|
const char *m_units;
|
||||||
T &m_value;
|
T &m_value;
|
||||||
|
|
||||||
bool m_has_range;
|
bool m_has_range;
|
||||||
T m_min;
|
T m_min, m_max;
|
||||||
T m_max;
|
|
||||||
bool m_has_default;
|
bool m_has_default;
|
||||||
T m_default;
|
T m_default;
|
||||||
|
|
||||||
@@ -101,6 +102,8 @@ public:
|
|||||||
bool has_default() const { return m_has_default; }
|
bool has_default() const { return m_has_default; }
|
||||||
const T& default_val() const { return m_default; }
|
const T& default_val() const { return m_default; }
|
||||||
|
|
||||||
|
static constexpr bool is_read_only() { return false; }
|
||||||
|
|
||||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
template <class Archivex>
|
template <class Archivex>
|
||||||
@@ -114,11 +117,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline hrp<T> make_hrp(const char *name, T &t, const char* units = nullptr) {
|
|
||||||
return hrp<T>(name, t, units);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class hrp_enum : public boost::serialization::wrapper_traits<hrp_enum<T>> {
|
class hrp_enum : public boost::serialization::wrapper_traits<hrp_enum<T>> {
|
||||||
const char *m_name;
|
const char *m_name;
|
||||||
@@ -142,6 +140,8 @@ public:
|
|||||||
bool has_default() const { return m_has_default; }
|
bool has_default() const { return m_has_default; }
|
||||||
const T& default_val() const { return m_default; }
|
const T& default_val() const { return m_default; }
|
||||||
|
|
||||||
|
static constexpr bool is_read_only() { return false; }
|
||||||
|
|
||||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
template <class Archivex>
|
template <class Archivex>
|
||||||
@@ -155,13 +155,121 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class hrp_val : public boost::serialization::wrapper_traits<hrp_val<T>> {
|
||||||
|
const char *m_name;
|
||||||
|
const char *m_units;
|
||||||
|
T m_value;
|
||||||
|
bool m_has_range;
|
||||||
|
T m_min, m_max;
|
||||||
|
bool m_has_default;
|
||||||
|
T m_default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit hrp_val(const char *name_, T t, const char* units_ = nullptr)
|
||||||
|
: m_name(name_), m_units(units_), m_value(t), m_has_range(false), m_has_default(false) {}
|
||||||
|
|
||||||
|
hrp_val& range(const T& min_val, const T& max_val) { m_min = min_val; m_max = max_val; m_has_range = true; return *this; }
|
||||||
|
hrp_val& set_default(const T& def_val) { m_default = def_val; m_has_default = true; return *this; }
|
||||||
|
|
||||||
|
const char *name() const { return this->m_name; }
|
||||||
|
const char *units() const { return this->m_units; }
|
||||||
|
T &value() { return this->m_value; }
|
||||||
|
const T &const_value() const { return this->m_value; }
|
||||||
|
|
||||||
|
bool has_range() const { return m_has_range; }
|
||||||
|
const T& min_val() const { return m_min; }
|
||||||
|
const T& max_val() const { return m_max; }
|
||||||
|
bool has_default() const { return m_has_default; }
|
||||||
|
const T& default_val() const { return m_default; }
|
||||||
|
|
||||||
|
static constexpr bool is_read_only() { return true; }
|
||||||
|
|
||||||
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
|
template <class Archivex>
|
||||||
|
void save(Archivex &ar, const unsigned int /* version */) const {
|
||||||
|
ar << boost::serialization::make_nvp(m_name, m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archivex>
|
||||||
|
void load(Archivex &ar, const unsigned int /* version */) {
|
||||||
|
// Only for output archives
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class hrp_enum_val : public boost::serialization::wrapper_traits<hrp_enum_val<T>> {
|
||||||
|
const char *m_name;
|
||||||
|
const char *m_units;
|
||||||
|
T m_value;
|
||||||
|
std::vector<std::string> m_labels;
|
||||||
|
bool m_has_default;
|
||||||
|
T m_default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit hrp_enum_val(const char *name_, T t, const std::vector<std::string>& labels, const char* units_ = nullptr)
|
||||||
|
: m_name(name_), m_units(units_), m_value(t), m_labels(labels), m_has_default(false) {}
|
||||||
|
|
||||||
|
hrp_enum_val& set_default(const T& def_val) { m_default = def_val; m_has_default = true; return *this; }
|
||||||
|
|
||||||
|
const char *name() const { return this->m_name; }
|
||||||
|
const char *units() const { return this->m_units; }
|
||||||
|
T &value() { return this->m_value; }
|
||||||
|
const std::vector<std::string>& labels() const { return m_labels; }
|
||||||
|
|
||||||
|
bool has_default() const { return m_has_default; }
|
||||||
|
const T& default_val() const { return m_default; }
|
||||||
|
|
||||||
|
static constexpr bool is_read_only() { return true; }
|
||||||
|
|
||||||
|
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||||
|
|
||||||
|
template <class Archivex>
|
||||||
|
void save(Archivex &ar, const unsigned int /* version */) const {
|
||||||
|
ar << boost::serialization::make_nvp(m_name, m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archivex>
|
||||||
|
void load(Archivex &ar, const unsigned int /* version */) {
|
||||||
|
// Only for output archives
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline hrp<T> make_hrp(const char *name, T &t, const char* units = nullptr) {
|
||||||
|
return hrp<T>(name, t, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specialization for rvalues (value-based storage)
|
||||||
|
template <class T>
|
||||||
|
inline hrp_val<T> make_hrp(const char *name, T &&t, const char* units = nullptr) {
|
||||||
|
return hrp_val<T>(name, t, units);
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline hrp_enum<T> make_hrp_enum(const char *name, T &t, const std::vector<std::string>& labels, const char* units = nullptr) {
|
inline hrp_enum<T> make_hrp_enum(const char *name, T &t, const std::vector<std::string>& labels, const char* units = nullptr) {
|
||||||
return hrp_enum<T>(name, t, labels, units);
|
return hrp_enum<T>(name, t, labels, units);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HRP(name) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name)
|
// Specialization for rvalues (value-based storage)
|
||||||
#define HRPU(name, units) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name, units)
|
template <class T>
|
||||||
|
inline hrp_enum_val<T> make_hrp_enum(const char *name, T &&t, const std::vector<std::string>& labels, const char* units = nullptr) {
|
||||||
|
return hrp_enum_val<T>(name, t, labels, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline hrp<T> make_nvp(const char *name, T &t, const char* units) {
|
||||||
|
return hrp<T>(name, t, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specialization for rvalues (value-based storage)
|
||||||
|
template <class T>
|
||||||
|
inline hrp_val<T> make_nvp(const char *name, T &&t, const char* units) {
|
||||||
|
return hrp_val<T>(name, t, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace serialization
|
} // namespace serialization
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
@@ -181,7 +289,41 @@ namespace uLib {
|
|||||||
|
|
||||||
#define _AR_OP(r, data, elem) data &BOOST_SERIALIZATION_BASE_OBJECT_NVP(elem);
|
#define _AR_OP(r, data, elem) data &BOOST_SERIALIZATION_BASE_OBJECT_NVP(elem);
|
||||||
|
|
||||||
#define NVP(data) BOOST_SERIALIZATION_NVP(data)
|
// NAME VALUE PAIR //
|
||||||
|
#define NVP_GET_MACRO(_1, _2, _3, NAME, ...) NAME
|
||||||
|
#define NVP(...) NVP_GET_MACRO(__VA_ARGS__, NVP3, NVP2, NVP1)(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define NVP1(data) BOOST_SERIALIZATION_NVP(data)
|
||||||
|
#define NVP2(name, data) boost::serialization::make_nvp(name, data)
|
||||||
|
#define NVP3(name, data, units) boost::serialization::make_nvp(name, data, units)
|
||||||
|
|
||||||
|
|
||||||
|
// HUMAN READABLE PROPERTY //
|
||||||
|
#define HRP_GET_MACRO(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
|
||||||
|
#define HRP(...) HRP_GET_MACRO(__VA_ARGS__, HRP6, HRP5, HRP4, HRP3, HRP2, HRP1)(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define HRP1(data) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(data), data)
|
||||||
|
#define HRP2(name, data) boost::serialization::make_hrp(name, data)
|
||||||
|
#define HRP3(name, data, units) boost::serialization::make_hrp(name, data, units)
|
||||||
|
#define HRP4(name, data, units, default) boost::serialization::make_hrp(name, data, units).set_default(default)
|
||||||
|
#define HRP5(name, data, units, min, max) boost::serialization::make_hrp(name, data, units).range(min, max)
|
||||||
|
#define HRP6(name, data, units, default, min, max) boost::serialization::make_hrp(name, data, units).set_default(default).range(min, max)
|
||||||
|
|
||||||
|
#define HRPE(name, data, labels) boost::serialization::make_hrp_enum(name, data, labels)
|
||||||
|
|
||||||
|
// LEFT FOR BACKWARD COMPATIBILITY
|
||||||
|
#define HRPU(name, units) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name, units)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace serialization {
|
||||||
|
using boost::serialization::make_nvp;
|
||||||
|
using boost::serialization::make_hrp;
|
||||||
|
using boost::serialization::make_hrp_enum;
|
||||||
|
} // serialization
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -209,7 +351,7 @@ namespace uLib {
|
|||||||
#define ULIB_SERIALIZE_OBJECT(_Ob, ...) \
|
#define ULIB_SERIALIZE_OBJECT(_Ob, ...) \
|
||||||
_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob, __VA_ARGS__)
|
_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob, __VA_ARGS__)
|
||||||
#define AR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name)
|
#define AR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name)
|
||||||
#define HR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name)
|
#define HR(_name) _ULIB_DETAIL_UNINTRUSIVE_HR_(_name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ULIB_SERIALIZE_ACCESS \
|
#define ULIB_SERIALIZE_ACCESS \
|
||||||
@@ -222,14 +364,14 @@ namespace uLib {
|
|||||||
#define ULIB_CLASS_EXPORT_OBJECT_KEY(_FullNamespaceClass) \
|
#define ULIB_CLASS_EXPORT_OBJECT_KEY(_FullNamespaceClass) \
|
||||||
BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass)
|
BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass)
|
||||||
|
|
||||||
#define _SERIALIZE_IMPL_SEQ \
|
#define _SERIALIZE_IMPL_SEQ \
|
||||||
(uLib::Archive::text_iarchive)(uLib::Archive::text_oarchive)( \
|
(uLib::Archive::text_iarchive) \
|
||||||
uLib::Archive:: \
|
(uLib::Archive::text_oarchive) \
|
||||||
hrt_iarchive)(uLib::Archive:: \
|
(uLib::Archive::hrt_iarchive) \
|
||||||
hrt_oarchive)(uLib::Archive:: \
|
(uLib::Archive::hrt_oarchive) \
|
||||||
xml_iarchive)(uLib::Archive:: \
|
(uLib::Archive::xml_iarchive) \
|
||||||
xml_oarchive)(uLib::Archive:: \
|
(uLib::Archive::xml_oarchive) \
|
||||||
log_archive)
|
(uLib::Archive::log_archive)
|
||||||
|
|
||||||
/** Solving virtual class check problem */
|
/** Solving virtual class check problem */
|
||||||
#define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(_Base, _Derived) \
|
#define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(_Base, _Derived) \
|
||||||
@@ -300,6 +442,11 @@ namespace uLib {
|
|||||||
template <class ArchiveT> \
|
template <class ArchiveT> \
|
||||||
void _Ob::save_override(ArchiveT &ar, const unsigned int version)
|
void _Ob::save_override(ArchiveT &ar, const unsigned int version)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -404,7 +551,8 @@ namespace uLib {
|
|||||||
void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \
|
void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \
|
||||||
/* PP serialize */ BOOST_PP_SEQ_FOR_EACH( \
|
/* PP serialize */ BOOST_PP_SEQ_FOR_EACH( \
|
||||||
_UNAR_OP, ob, BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); \
|
_UNAR_OP, ob, BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); \
|
||||||
/* MPL serialize */ /*uLib::mpl::for_each<_Ob::BaseList>(uLib::detail::Serializable::serialize_baseobject<_Ob,ArchiveT>(ob,ar) );*/ } \
|
/* MPL serialize */ /*uLib::mpl::for_each<_Ob::BaseList> \
|
||||||
|
(uLib::detail::Serializable::serialize_baseobject<_Ob,ArchiveT>(ob,ar) );*/ }\
|
||||||
template <class ArchiveT> \
|
template <class ArchiveT> \
|
||||||
inline void load_construct_data(ArchiveT &ar, _Ob *ob, \
|
inline void load_construct_data(ArchiveT &ar, _Ob *ob, \
|
||||||
const unsigned int file_version) { \
|
const unsigned int file_version) { \
|
||||||
@@ -429,8 +577,16 @@ namespace uLib {
|
|||||||
void boost::serialization::access2<_Ob>::save_override( \
|
void boost::serialization::access2<_Ob>::save_override( \
|
||||||
ArchiveT &ar, _Ob &ob, const unsigned int version)
|
ArchiveT &ar, _Ob &ob, const unsigned int version)
|
||||||
|
|
||||||
|
|
||||||
#define _ULIB_DETAIL_UNINTRUSIVE_AR_(name) \
|
#define _ULIB_DETAIL_UNINTRUSIVE_AR_(name) \
|
||||||
boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), ob.name)
|
boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), ob.name)
|
||||||
|
#define _ULIB_DETAIL_UNINTRUSIVE_HR_(name) \
|
||||||
|
boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), ob.name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ set( TESTS
|
|||||||
OpenMPTest
|
OpenMPTest
|
||||||
TeamTest
|
TeamTest
|
||||||
AffinityTest
|
AffinityTest
|
||||||
|
ReadOnlyPropertyTest
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
|
|||||||
@@ -23,74 +23,138 @@
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <boost/signals2/signal.hpp>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
#include "Core/Object.h"
|
#include "Core/Object.h"
|
||||||
|
#include "Core/Property.h"
|
||||||
|
#include "Core/Archives.h"
|
||||||
|
#include "Core/Serializable.h"
|
||||||
#include "testing-prototype.h"
|
#include "testing-prototype.h"
|
||||||
|
|
||||||
#define emit
|
using namespace uLib;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, bool copyable = true>
|
|
||||||
class property
|
|
||||||
{
|
|
||||||
typedef boost::signals2::signal<void(const property<T>& )> signal_t;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A test class to demonstrate property registration via SERIALIZE_OBJECT.
|
||||||
|
*/
|
||||||
|
class TestObject : public Object {
|
||||||
public:
|
public:
|
||||||
property() : m_changed(new signal_t) {}
|
uLibTypeMacro(TestObject, Object)
|
||||||
property(const T in) : value(in) , m_changed(new signal_t) {}
|
|
||||||
|
|
||||||
inline operator T const & () const { return value; }
|
TestObject() : m_Value(10.5f), m_Status("Initialized"), m_Counter(0) {}
|
||||||
inline operator T & () { return value; }
|
|
||||||
inline T & operator = (const T &i) { value = i; return value; }
|
float m_Value;
|
||||||
template <typename T2> T2 & operator = (const T2 &i) { T2 &guard = value; } // Assign exact identical types only.
|
std::string m_Status;
|
||||||
inline signal_t & valueChanged() { return *m_changed; }
|
int m_Counter;
|
||||||
|
|
||||||
|
// Static properties (registered in constructor/initializer)
|
||||||
|
ULIB_PROPERTY(int, StaticProp, 42)
|
||||||
|
|
||||||
|
ULIB_SERIALIZE_ACCESS
|
||||||
|
|
||||||
|
template <typename Ar>
|
||||||
|
void serialize(Ar& ar, unsigned int version) {
|
||||||
|
ar & HRP("value", m_Value, "mm").range(0, 100).set_default(1.);
|
||||||
|
ar & HRP("status", m_Status);
|
||||||
|
ar & HRP("counter", m_Counter);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
T value;
|
|
||||||
boost::shared_ptr<signal_t> m_changed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//template <typename T>
|
class TestObject2 : public TestObject {
|
||||||
//class property <T,false> {
|
public:
|
||||||
// typedef boost::signals2::signal<void( T )> signal_t;
|
uLibTypeMacro(TestObject2, TestObject)
|
||||||
|
|
||||||
//public:
|
TestObject2() : TestObject(), m_Value2(20.5f) {}
|
||||||
// property() : m_changed() {}
|
|
||||||
// property(const T in) : value(in) , m_changed() {}
|
|
||||||
|
|
||||||
// inline operator T const & () const { return value; }
|
float m_Value2;
|
||||||
// inline operator T & () { valueChanged()(value); return value; }
|
|
||||||
// inline T & operator = (const T &i) { value = i; valueChanged()(value); return value; }
|
|
||||||
// template <typename T2> T2 & operator = (const T2 &i) { T2 &guard = value; } // Assign exact identical types only.
|
|
||||||
// inline signal_t &valueChanged() { return m_changed; }
|
|
||||||
|
|
||||||
//private:
|
|
||||||
// property(const property<T> &);
|
|
||||||
// property<T> &operator = (const property<T>&);
|
|
||||||
|
|
||||||
// T value;
|
|
||||||
// signal_t m_changed;
|
|
||||||
//};
|
|
||||||
|
|
||||||
// test generic void function slot //
|
|
||||||
void PrintSlot(const property<int> &i) { std::cout << "slot called, new value = " << i << "!\n"; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
ULIB_SERIALIZE_ACCESS
|
||||||
|
};
|
||||||
|
|
||||||
|
ULIB_SERIALIZABLE_OBJECT(TestObject2)
|
||||||
|
ULIB_SERIALIZE_OBJECT(TestObject2, TestObject) {
|
||||||
|
std::cout << "Serializing TestObject2" << std::endl;
|
||||||
|
// ar & boost::serialization::make_hrp("value2", ob.m_Value2, "mm").set_default(1.);
|
||||||
|
ar & HRP("value2", ob.m_Value2, "mm").set_default(1.);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
BEGIN_TESTING(Properties Serialization)
|
||||||
|
|
||||||
|
TestObject obj;
|
||||||
|
|
||||||
|
// 1. Initial state: check static property
|
||||||
|
ASSERT_EQUAL(obj.StaticProp, 42);
|
||||||
|
|
||||||
|
// 2. Activate dynamic properties via the property_register_archive
|
||||||
|
// This calls the serialize method with a special archive that populates m_DynamicProperties
|
||||||
|
ULIB_ACTIVATE_PROPERTIES(obj);
|
||||||
|
|
||||||
|
const auto& props = obj.GetProperties();
|
||||||
|
// This is problematic because GetProperties currently returns d->m_Properties (only static)
|
||||||
|
|
||||||
|
// For now, let's just assert on the dynamic property presence if possible
|
||||||
|
PropertyBase* pVal = obj.GetProperty("value");
|
||||||
|
ASSERT_NOT_NULL(pVal);
|
||||||
|
ASSERT_EQUAL(pVal->GetValueAsString(), "10.5");
|
||||||
|
ASSERT_EQUAL(pVal->GetUnits(), "mm");
|
||||||
|
|
||||||
|
// Check other dynamic properties
|
||||||
|
ASSERT_NOT_NULL(obj.GetProperty("status"));
|
||||||
|
ASSERT_NOT_NULL(obj.GetProperty("counter"));
|
||||||
|
|
||||||
|
// 4. Serialization round-trip (XML)
|
||||||
|
{
|
||||||
|
std::ofstream ofs("test_props.xml");
|
||||||
|
Archive::xml_oarchive(ofs) << NVP("test_obj", obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestObject obj2;
|
||||||
|
obj2.m_Value = 0;
|
||||||
|
obj2.m_Status = "";
|
||||||
|
{
|
||||||
|
std::ifstream ifs("test_props.xml");
|
||||||
|
Archive::xml_iarchive(ifs) >> NVP("test_obj", obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_EQUAL(obj2.m_Value, 10.5f);
|
||||||
|
ASSERT_EQUAL(obj2.m_Status, "Initialized");
|
||||||
|
|
||||||
|
TestObject2 obj3;
|
||||||
|
obj3.m_Value = 12.5;
|
||||||
|
obj3.m_Status = "Initialized";
|
||||||
|
obj3.m_Value2 = 22.5;
|
||||||
|
|
||||||
|
ULIB_ACTIVATE_PROPERTIES(obj3);
|
||||||
|
|
||||||
|
PropertyBase* pVal3 = obj3.GetProperty("value2");
|
||||||
|
ASSERT_NOT_NULL(pVal3);
|
||||||
|
ASSERT_EQUAL(pVal3->GetValueAsString(), "22.5");
|
||||||
|
ASSERT_EQUAL(pVal3->GetUnits(), "mm");
|
||||||
|
|
||||||
|
// 5. Serialization round-trip (XML)
|
||||||
|
{
|
||||||
|
std::ofstream ofs("test_props2.xml");
|
||||||
|
Archive::xml_oarchive(ofs) << NVP("test_obj2", obj3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestObject2 obj4;
|
||||||
|
obj4.m_Value = 0;
|
||||||
|
obj4.m_Status = "";
|
||||||
|
obj4.m_Value2 = 0;
|
||||||
|
ULIB_ACTIVATE_PROPERTIES(obj4);
|
||||||
|
{
|
||||||
|
std::ifstream ifs("test_props2.xml");
|
||||||
|
Archive::xml_iarchive(ifs) >> NVP("test_obj2", obj4);
|
||||||
|
}
|
||||||
|
ASSERT_EQUAL(obj4.m_Value, 12.5f);
|
||||||
|
ASSERT_EQUAL(obj4.m_Status, "Initialized");
|
||||||
|
ASSERT_EQUAL(obj4.m_Value2, 22.5f);
|
||||||
|
|
||||||
|
|
||||||
|
END_TESTING
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,12 @@ using namespace uLib;
|
|||||||
|
|
||||||
class TestObject : public Object {
|
class TestObject : public Object {
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(TestObject, Object)
|
||||||
TestObject() : Object(),
|
TestObject() : Object(),
|
||||||
IntProp(this, "IntProp", 10),
|
IntProp(this, "IntProp", 10),
|
||||||
StringProp(this, "StringProp", "Initial")
|
StringProp(this, "StringProp", "Initial")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual const char* GetClassName() const override { return "TestObject"; }
|
|
||||||
|
|
||||||
Property<int> IntProp;
|
Property<int> IntProp;
|
||||||
Property<std::string> StringProp;
|
Property<std::string> StringProp;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ using namespace uLib;
|
|||||||
|
|
||||||
class TestObject : public Object {
|
class TestObject : public Object {
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(TestObject, Object)
|
||||||
TestObject() : Object() {}
|
TestObject() : Object() {}
|
||||||
|
|
||||||
virtual const char* GetClassName() const override { return "TestObject"; }
|
|
||||||
|
|
||||||
// Use new typedefs
|
// Use new typedefs
|
||||||
StringProperty StringProp = StringProperty(this, "StringProp", "Initial");
|
StringProperty StringProp = StringProperty(this, "StringProp", "Initial");
|
||||||
IntProperty IntProp = IntProperty(this, "IntProp", 42);
|
IntProperty IntProp = IntProperty(this, "IntProp", 42);
|
||||||
|
|||||||
82
src/Core/testing/ReadOnlyPropertyTest.cpp
Normal file
82
src/Core/testing/ReadOnlyPropertyTest.cpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cassert>
|
||||||
|
#include "Core/Object.h"
|
||||||
|
#include "Core/Property.h"
|
||||||
|
#include "Core/Serializable.h"
|
||||||
|
|
||||||
|
#include "Core/Serializable.h"
|
||||||
|
|
||||||
|
using namespace uLib;
|
||||||
|
|
||||||
|
class ReadOnlyTestObject : public Object {
|
||||||
|
public:
|
||||||
|
int m_value;
|
||||||
|
int getValue() const { return m_value; }
|
||||||
|
|
||||||
|
enum State { State1, State2 };
|
||||||
|
State m_state;
|
||||||
|
State getState() const { return m_state; }
|
||||||
|
|
||||||
|
ReadOnlyTestObject() : m_value(10), m_state(State1) {
|
||||||
|
ULIB_ACTIVATE_PROPERTIES(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int version) {
|
||||||
|
// Lvalue reference - should be NOT read-only
|
||||||
|
ar & HRP("lvalue_prop", m_value);
|
||||||
|
|
||||||
|
// Rvalue from getter - should be read-only
|
||||||
|
ar & HRP("rvalue_prop", getValue());
|
||||||
|
|
||||||
|
// Enum lvalue - should be NOT read-only
|
||||||
|
ar & boost::serialization::make_hrp_enum("lvalue_enum", (int&)m_state, {"State1", "State2"});
|
||||||
|
|
||||||
|
// Enum rvalue - should be read-only
|
||||||
|
ar & boost::serialization::make_hrp_enum("rvalue_enum", (int)getState(), {"State1", "State2"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Testing Read-Only Property Feature..." << std::endl;
|
||||||
|
|
||||||
|
ReadOnlyTestObject obj;
|
||||||
|
const auto& props = obj.GetProperties();
|
||||||
|
|
||||||
|
std::cout << "Registered Properties in ReadOnlyTestObject:" << std::endl;
|
||||||
|
bool found_lvalue = false;
|
||||||
|
bool found_rvalue = false;
|
||||||
|
bool found_lvalue_enum = false;
|
||||||
|
bool found_rvalue_enum = false;
|
||||||
|
|
||||||
|
for (auto* p : props) {
|
||||||
|
bool ro = p->IsReadOnly();
|
||||||
|
std::cout << " - Name: " << p->GetName()
|
||||||
|
<< " | Type: " << p->GetTypeName()
|
||||||
|
<< " | ReadOnly: " << (ro ? "YES" : "NO") << std::endl;
|
||||||
|
|
||||||
|
if (p->GetName() == "lvalue_prop") {
|
||||||
|
if (ro) { std::cerr << "FAIL: lvalue_prop should NOT be read-only" << std::endl; return 1; }
|
||||||
|
found_lvalue = true;
|
||||||
|
} else if (p->GetName() == "rvalue_prop") {
|
||||||
|
if (!ro) { std::cerr << "FAIL: rvalue_prop SHOULD be read-only" << std::endl; return 1; }
|
||||||
|
found_rvalue = true;
|
||||||
|
} else if (p->GetName() == "lvalue_enum") {
|
||||||
|
if (ro) { std::cerr << "FAIL: lvalue_enum should NOT be read-only" << std::endl; return 1; }
|
||||||
|
found_lvalue_enum = true;
|
||||||
|
} else if (p->GetName() == "rvalue_enum") {
|
||||||
|
if (!ro) { std::cerr << "FAIL: rvalue_enum SHOULD be read-only" << std::endl; return 1; }
|
||||||
|
found_rvalue_enum = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_lvalue && found_rvalue && found_lvalue_enum && found_rvalue_enum) {
|
||||||
|
std::cout << "TEST PASSED SUCCESSFULLY!" << std::endl;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
std::cerr << "TEST FAILED: Some properties were not found!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,7 +40,7 @@ struct A : Object {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ULIB_SERIALIZABLE_OBJECT(A)
|
ULIB_SERIALIZABLE_OBJECT(A)
|
||||||
ULIB_SERIALIZE_OBJECT(A, Object) { ar &AR(numa); }
|
ULIB_SERIALIZE_OBJECT(A, Object) { ar & AR(numa); }
|
||||||
|
|
||||||
struct B : virtual Object {
|
struct B : virtual Object {
|
||||||
uLibTypeMacro(B, Object) B() : numb(5552369) {}
|
uLibTypeMacro(B, Object) B() : numb(5552369) {}
|
||||||
@@ -48,7 +48,7 @@ struct B : virtual Object {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ULIB_SERIALIZABLE_OBJECT(B)
|
ULIB_SERIALIZABLE_OBJECT(B)
|
||||||
ULIB_SERIALIZE_OBJECT(B, Object) { ar &AR(numb); }
|
ULIB_SERIALIZE_OBJECT(B, Object) { ar & AR(numb); }
|
||||||
|
|
||||||
struct C : B {
|
struct C : B {
|
||||||
uLibTypeMacro(C, B) C() : numc(5552370) {}
|
uLibTypeMacro(C, B) C() : numc(5552370) {}
|
||||||
@@ -56,7 +56,7 @@ struct C : B {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ULIB_SERIALIZABLE_OBJECT(C)
|
ULIB_SERIALIZABLE_OBJECT(C)
|
||||||
ULIB_SERIALIZE_OBJECT(C, B) { ar &AR(numc); }
|
ULIB_SERIALIZE_OBJECT(C, B) { ar & AR(numc); }
|
||||||
|
|
||||||
struct D : A, B {
|
struct D : A, B {
|
||||||
uLibTypeMacro(D, A, B)
|
uLibTypeMacro(D, A, B)
|
||||||
@@ -67,10 +67,33 @@ struct D : A, B {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ULIB_SERIALIZABLE_OBJECT(D)
|
ULIB_SERIALIZABLE_OBJECT(D)
|
||||||
ULIB_SERIALIZE_OBJECT(D, A, B) { ar &AR(numd); }
|
ULIB_SERIALIZE_OBJECT(D, A, B) { ar & AR(numd); }
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
A o;
|
BEGIN_TESTING(DreadDiamond Serialization)
|
||||||
|
|
||||||
Archive::xml_oarchive(std::cout) << NVP(o);
|
D o;
|
||||||
|
C c;
|
||||||
|
c.numb = 123;
|
||||||
|
{
|
||||||
|
std::ofstream file("test.xml");
|
||||||
|
Archive::xml_oarchive(file) << NVP("dd_test", o) << NVP("c", c);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
D o2;
|
||||||
|
C c2;
|
||||||
|
std::ifstream file("test.xml");
|
||||||
|
Archive::xml_iarchive(file) >> NVP("dd_test", o2) >> NVP("c", c2);
|
||||||
|
|
||||||
|
// D //
|
||||||
|
ASSERT_EQUAL(o.numa, o2.numa);
|
||||||
|
ASSERT_EQUAL(o.numb, o2.numb);
|
||||||
|
ASSERT_EQUAL(o.numd, o2.numd);
|
||||||
|
|
||||||
|
// C //
|
||||||
|
ASSERT_EQUAL(c.numb, c2.numb);
|
||||||
|
ASSERT_EQUAL(c.numc, c2.numc);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_TESTING
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,22 +143,19 @@ int testing_hrt_class() {
|
|||||||
}
|
}
|
||||||
a.a() = 0;
|
a.a() = 0;
|
||||||
a.p_a = "zero string";
|
a.p_a = "zero string";
|
||||||
{
|
|
||||||
// ERRORE FIX !
|
|
||||||
// std::ifstream file("test.xml");
|
|
||||||
// Archive::hrt_iarchive(file) >> NVP(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
Archive::hrt_oarchive(std::cout) << NVP(a);
|
Archive::hrt_oarchive(std::cout) << NVP(a);
|
||||||
return (a.a() == 5552368 && a.p_a == "A property string");
|
return (a.a() == 5552368 && a.p_a == "A property string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
BEGIN_TESTING(Serialize Test);
|
BEGIN_TESTING(Serialize Test);
|
||||||
|
|
||||||
TEST1(test_V3f());
|
TEST1(test_V3f());
|
||||||
TEST1(testing_xml_class());
|
TEST1(testing_xml_class());
|
||||||
// testing_hrt_class(); ///// << ERRORE in HRT with properties
|
// TEST1(testing_hrt_class());
|
||||||
|
|
||||||
END_TESTING;
|
END_TESTING;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,10 @@ namespace uLib {
|
|||||||
|
|
||||||
class DetectorChamber : public ContainerBox {
|
class DetectorChamber : public ContainerBox {
|
||||||
|
|
||||||
typedef ContainerBox BaseClass;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(DetectorChamber, ContainerBox)
|
||||||
|
|
||||||
|
|
||||||
virtual const char * GetClassName() const { return "DetectorChamber"; }
|
|
||||||
|
|
||||||
DetectorChamber() : BaseClass() {
|
DetectorChamber() : BaseClass() {
|
||||||
m_ProjectionPlane.origin = HPoint3f(0, 0, 0);
|
m_ProjectionPlane.origin = HPoint3f(0, 0, 0);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ set(SOURCES
|
|||||||
Scene.cpp
|
Scene.cpp
|
||||||
Solid.cpp
|
Solid.cpp
|
||||||
EmitterPrimary.cpp
|
EmitterPrimary.cpp
|
||||||
|
Matter.cpp
|
||||||
|
GeantRegistration.cpp
|
||||||
DetectorConstruction.cpp
|
DetectorConstruction.cpp
|
||||||
PhysicsList.cpp
|
PhysicsList.cpp
|
||||||
ActionInitialization.cpp
|
ActionInitialization.cpp
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ namespace Geant {
|
|||||||
class EmitterPrimary : public G4VUserPrimaryGeneratorAction, public AffineTransform
|
class EmitterPrimary : public G4VUserPrimaryGeneratorAction, public AffineTransform
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(EmitterPrimary, Object)
|
||||||
virtual const char* GetClassName() const override { return "Geant.EmitterPrimary"; }
|
|
||||||
|
|
||||||
EmitterPrimary();
|
EmitterPrimary();
|
||||||
virtual ~EmitterPrimary();
|
virtual ~EmitterPrimary();
|
||||||
@@ -47,8 +46,7 @@ class EmitterPrimary : public G4VUserPrimaryGeneratorAction, public AffineTransf
|
|||||||
class SkyPlaneEmitterPrimary : public EmitterPrimary
|
class SkyPlaneEmitterPrimary : public EmitterPrimary
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(SkyPlaneEmitterPrimary, EmitterPrimary)
|
||||||
virtual const char* GetClassName() const override { return "Geant.SkyPlaneEmitterPrimary"; }
|
|
||||||
|
|
||||||
SkyPlaneEmitterPrimary();
|
SkyPlaneEmitterPrimary();
|
||||||
virtual ~SkyPlaneEmitterPrimary();
|
virtual ~SkyPlaneEmitterPrimary();
|
||||||
@@ -69,8 +67,7 @@ class SkyPlaneEmitterPrimary : public EmitterPrimary
|
|||||||
class CylinderEmitterPrimary : public EmitterPrimary
|
class CylinderEmitterPrimary : public EmitterPrimary
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(CylinderEmitterPrimary, EmitterPrimary)
|
||||||
virtual const char* GetClassName() const override { return "Geant.CylinderEmitterPrimary"; }
|
|
||||||
|
|
||||||
CylinderEmitterPrimary();
|
CylinderEmitterPrimary();
|
||||||
virtual ~CylinderEmitterPrimary();
|
virtual ~CylinderEmitterPrimary();
|
||||||
@@ -98,8 +95,7 @@ class CylinderEmitterPrimary : public EmitterPrimary
|
|||||||
class QuadMeshEmitterPrimary : public EmitterPrimary
|
class QuadMeshEmitterPrimary : public EmitterPrimary
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(QuadMeshEmitterPrimary, EmitterPrimary)
|
||||||
virtual const char* GetClassName() const override { return "Geant.QuadMeshEmitterPrimary"; }
|
|
||||||
|
|
||||||
QuadMeshEmitterPrimary();
|
QuadMeshEmitterPrimary();
|
||||||
virtual ~QuadMeshEmitterPrimary();
|
virtual ~QuadMeshEmitterPrimary();
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ class SteppingAction;
|
|||||||
class GeantEvent : public Object {
|
class GeantEvent : public Object {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(GeantEvent, Object)
|
||||||
virtual const char* GetClassName() const override { return "Geant.GeantEvent"; }
|
|
||||||
|
|
||||||
/// A single interaction step along the muon path.
|
/// A single interaction step along the muon path.
|
||||||
struct Delta {
|
struct Delta {
|
||||||
|
|||||||
22
src/HEP/Geant/GeantRegistration.cpp
Normal file
22
src/HEP/Geant/GeantRegistration.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "Core/ObjectFactory.h"
|
||||||
|
#include "HEP/Geant/Matter.h"
|
||||||
|
#include "HEP/Geant/Solid.h"
|
||||||
|
#include "HEP/Geant/Scene.h"
|
||||||
|
#include "HEP/Geant/EmitterPrimary.hh"
|
||||||
|
#include "HEP/Geant/GeantEvent.h"
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Geant {
|
||||||
|
|
||||||
|
ULIB_REGISTER_OBJECT(Material)
|
||||||
|
ULIB_REGISTER_OBJECT(Solid)
|
||||||
|
ULIB_REGISTER_OBJECT(TessellatedSolid)
|
||||||
|
ULIB_REGISTER_OBJECT(BoxSolid)
|
||||||
|
ULIB_REGISTER_OBJECT(Scene)
|
||||||
|
ULIB_REGISTER_OBJECT(SkyPlaneEmitterPrimary)
|
||||||
|
ULIB_REGISTER_OBJECT(CylinderEmitterPrimary)
|
||||||
|
ULIB_REGISTER_OBJECT(QuadMeshEmitterPrimary)
|
||||||
|
ULIB_REGISTER_OBJECT(GeantEvent)
|
||||||
|
|
||||||
|
} // namespace Geant
|
||||||
|
} // namespace uLib
|
||||||
21
src/HEP/Geant/Matter.cpp
Normal file
21
src/HEP/Geant/Matter.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
#include "HEP/Geant/Matter.h"
|
||||||
|
#include <Geant4/G4Material.hh>
|
||||||
|
#include <Geant4/G4NistManager.hh>
|
||||||
|
|
||||||
|
using namespace uLib::Geant;
|
||||||
|
|
||||||
|
Material::Material() : m_G4Data(nullptr) {}
|
||||||
|
|
||||||
|
Material::Material(const char *name) : m_G4Data(nullptr) {
|
||||||
|
this->SetFromNist(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Material::~Material() {
|
||||||
|
if(m_G4Data) delete m_G4Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::SetFromNist(const char *name) {
|
||||||
|
G4NistManager* man = G4NistManager::Instance();
|
||||||
|
m_G4Data = man->FindOrBuildMaterial(name);
|
||||||
|
}
|
||||||
@@ -29,9 +29,10 @@
|
|||||||
#define MATTER_H
|
#define MATTER_H
|
||||||
|
|
||||||
#include "Core/Object.h"
|
#include "Core/Object.h"
|
||||||
|
#include <Geant4/G4Material.hh>
|
||||||
|
#include <Geant4/G4NistManager.hh>
|
||||||
|
|
||||||
class G4Element;
|
class G4Element;
|
||||||
class G4Material;
|
|
||||||
|
|
||||||
namespace uLib {
|
namespace uLib {
|
||||||
namespace Geant {
|
namespace Geant {
|
||||||
@@ -55,18 +56,53 @@ private:
|
|||||||
//// MATERIAL //////////////////////////////////////////////////////////////////
|
//// MATERIAL //////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: finish from G4NistMaterialBuilder
|
||||||
|
|
||||||
class Material : public Object {
|
class Material : public Object {
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(Material, Object)
|
||||||
|
|
||||||
virtual const char* GetClassName() const override { return "Geant.Material"; }
|
enum State {
|
||||||
|
Undefined = 0,
|
||||||
|
Solid,
|
||||||
|
Liquid,
|
||||||
|
Gas
|
||||||
|
};
|
||||||
|
|
||||||
|
Material();
|
||||||
|
Material(const char *name);
|
||||||
|
~Material();
|
||||||
|
|
||||||
|
void SetFromNist(const char *name);
|
||||||
|
|
||||||
|
template <typename Ar>
|
||||||
|
void serialize(Ar &ar) {
|
||||||
|
ar & HRP("name", m_G4Data->GetName());
|
||||||
|
ar & HRP("density", m_G4Data->GetDensity());
|
||||||
|
ar & serialization::make_hrp_enum("state", m_G4Data->GetState(), {"Undefined", "Solid", "Liquid", "Gas"});
|
||||||
|
}
|
||||||
|
|
||||||
|
G4Material *GetG4Material() { return m_G4Data; }
|
||||||
|
|
||||||
uLibRefMacro(G4Data,G4Material *)
|
|
||||||
private:
|
private:
|
||||||
G4Material *m_G4Data;
|
G4Material *m_G4Data;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// class MaterialCompound : public Material {
|
||||||
|
// public:
|
||||||
|
|
||||||
|
// MaterialCompound(const char *name) {}
|
||||||
|
|
||||||
|
// void AddMaterial(Material *m, double fractionmass) { m_Materials.push_back(std::make_pair(m, fractionmass)); }
|
||||||
|
// void AddElement(Element *e, double fractionmass) { m_Elements.push_back(std::make_pair(e, fractionmass)); }
|
||||||
|
// void SetDensity(double density) { m_Density = density; }
|
||||||
|
|
||||||
|
// private:
|
||||||
|
// std::vector<std::pair<Material *, double>> m_Materials;
|
||||||
|
// std::vector<std::pair<Element *, double>> m_Elements;
|
||||||
|
// double m_Density;
|
||||||
|
// };
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ class EmitterPrimary;
|
|||||||
|
|
||||||
class Scene : public Object {
|
class Scene : public Object {
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(Scene, Object)
|
||||||
virtual const char* GetClassName() const override { return "Geant.Scene"; }
|
|
||||||
|
|
||||||
Scene();
|
Scene();
|
||||||
~Scene();
|
~Scene();
|
||||||
|
|||||||
@@ -146,6 +146,9 @@ void Solid::SetParent(Solid *parent) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TessellatedSolid::TessellatedSolid()
|
||||||
|
: BaseClass("unnamed_tessellated"), m_Solid(new G4TessellatedSolid("unnamed_tessellated")) {}
|
||||||
|
|
||||||
TessellatedSolid::TessellatedSolid(const char *name)
|
TessellatedSolid::TessellatedSolid(const char *name)
|
||||||
: BaseClass(name), m_Solid(new G4TessellatedSolid(name)) {
|
: BaseClass(name), m_Solid(new G4TessellatedSolid(name)) {
|
||||||
}
|
}
|
||||||
@@ -173,9 +176,15 @@ void TessellatedSolid::Update() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BoxSolid::BoxSolid(const char *name) :
|
||||||
|
BaseClass(name),
|
||||||
|
m_ContainerBox(new ContainerBox()),
|
||||||
|
m_Solid(new G4Box(name, 1, 1, 1))
|
||||||
|
{}
|
||||||
|
|
||||||
BoxSolid::BoxSolid(const char *name, ContainerBox *box) : BaseClass(name) {
|
BoxSolid::BoxSolid(const char *name, ContainerBox *box) : BaseClass(name) {
|
||||||
m_Solid = new G4Box(name, 1,1,1);
|
m_Solid = new G4Box(name, 1, 1, 1);
|
||||||
m_Object = box;
|
m_ContainerBox = box;
|
||||||
Object::connect(box, &ContainerBox::Updated, this, &BoxSolid::Update);
|
Object::connect(box, &ContainerBox::Updated, this, &BoxSolid::Update);
|
||||||
if (m_Logical) {
|
if (m_Logical) {
|
||||||
m_Logical->SetSolid(m_Solid);
|
m_Logical->SetSolid(m_Solid);
|
||||||
@@ -184,27 +193,30 @@ BoxSolid::BoxSolid(const char *name, ContainerBox *box) : BaseClass(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BoxSolid::Update() {
|
void BoxSolid::Update() {
|
||||||
if (m_Object) {
|
if (m_ContainerBox) {
|
||||||
Vector3f size = m_Object->GetSize();
|
Vector3f size = m_ContainerBox->GetSize();
|
||||||
m_Solid->SetXHalfLength(size(0) * 0.5);
|
m_Solid->SetXHalfLength(size(0) * 0.5);
|
||||||
m_Solid->SetYHalfLength(size(1) * 0.5);
|
m_Solid->SetYHalfLength(size(1) * 0.5);
|
||||||
m_Solid->SetZHalfLength(size(2) * 0.5);
|
m_Solid->SetZHalfLength(size(2) * 0.5);
|
||||||
|
|
||||||
// Geant4 placement is relative to center. uLib Box is anchored at corner.
|
// Geant4 placement is relative to center. uLib Box is anchored at corner.
|
||||||
// 1. Get position and rotation (clean, without scale)
|
// 1. Get position and rotation (clean, without scale)
|
||||||
Vector3f pos = m_Object->GetPosition();
|
Vector3f pos = m_ContainerBox->GetPosition();
|
||||||
Matrix3f rot = m_Object->GetRotation();
|
Matrix3f rot = m_ContainerBox->GetRotation();
|
||||||
|
|
||||||
// 2. Center = Corner + Rotation * (Half-Size)
|
// 2. Center = Corner + Rotation * (Half-Size)
|
||||||
// We must rotate the offset vector because uLib box can be rotated.
|
// We must rotate the offset vector because uLib box can be rotated.
|
||||||
Vector3f center = pos + rot * (size * 0.5);
|
Vector3f center = pos + rot * (size * 0.5);
|
||||||
|
|
||||||
uLib::AffineTransform t;
|
uLib::AffineTransform t;
|
||||||
t.SetPosition(center);
|
t.SetPosition(center);
|
||||||
t.SetRotation(rot);
|
t.SetRotation(rot);
|
||||||
|
|
||||||
this->SetTransform(t.GetMatrix());
|
this->SetTransform(t.GetMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ namespace Geant {
|
|||||||
|
|
||||||
class Solid : public Object {
|
class Solid : public Object {
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(Solid, Object)
|
||||||
virtual const char* GetClassName() const override { return "Geant.Solid"; }
|
|
||||||
|
|
||||||
Solid();
|
Solid();
|
||||||
Solid(const char *name);
|
Solid(const char *name);
|
||||||
@@ -52,6 +51,7 @@ public:
|
|||||||
|
|
||||||
void SetNistMaterial(const char *name);
|
void SetNistMaterial(const char *name);
|
||||||
void SetMaterial(G4Material *material);
|
void SetMaterial(G4Material *material);
|
||||||
|
|
||||||
void SetSizeUnit(const char *unit);
|
void SetSizeUnit(const char *unit);
|
||||||
// Implementiamo SetParent qui, per tutti.
|
// Implementiamo SetParent qui, per tutti.
|
||||||
virtual void SetParent(Solid *parent);
|
virtual void SetParent(Solid *parent);
|
||||||
@@ -69,6 +69,14 @@ public:
|
|||||||
return m_Logical ? m_Logical->GetName().c_str() : m_Name.c_str();
|
return m_Logical ? m_Logical->GetName().c_str() : m_Name.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename Ar >
|
||||||
|
void serialize(Ar &ar, const unsigned int version) {
|
||||||
|
ar & m_Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::string m_Name;
|
std::string m_Name;
|
||||||
@@ -84,11 +92,10 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
class TessellatedSolid : public Solid {
|
class TessellatedSolid : public Solid {
|
||||||
typedef Solid BaseClass;
|
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(TessellatedSolid, Solid)
|
||||||
|
|
||||||
virtual const char* GetClassName() const override { return "Geant.TessellatedSolid"; }
|
TessellatedSolid();
|
||||||
|
|
||||||
TessellatedSolid(const char *name);
|
TessellatedSolid(const char *name);
|
||||||
void SetMesh(TriangleMesh &mesh);
|
void SetMesh(TriangleMesh &mesh);
|
||||||
uLibGetMacro(Solid, G4TessellatedSolid *)
|
uLibGetMacro(Solid, G4TessellatedSolid *)
|
||||||
@@ -110,22 +117,27 @@ private :
|
|||||||
|
|
||||||
|
|
||||||
class BoxSolid : public Solid {
|
class BoxSolid : public Solid {
|
||||||
typedef Solid BaseClass;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
uLibTypeMacro(BoxSolid, Solid)
|
||||||
|
|
||||||
virtual const char* GetClassName() const override { return "Geant.BoxSolid"; }
|
BoxSolid(const char *name = "");
|
||||||
|
|
||||||
BoxSolid(const char *name, ContainerBox *box);
|
BoxSolid(const char *name, ContainerBox *box);
|
||||||
virtual G4VSolid* GetG4Solid() const override { return (G4VSolid*)m_Solid; }
|
virtual G4VSolid* GetG4Solid() const override { return (G4VSolid*)m_Solid; }
|
||||||
|
|
||||||
ContainerBox* GetObject() const { return m_Object; }
|
ContainerBox* GetObject() const { return m_ContainerBox; }
|
||||||
|
|
||||||
|
template < typename Ar >
|
||||||
|
void serialize(Ar &ar, const unsigned int version) {
|
||||||
|
ar & boost::serialization::base_object<BaseClass>(*this);
|
||||||
|
ar & m_ContainerBox;
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ContainerBox *m_Object;
|
ContainerBox *m_ContainerBox;
|
||||||
G4Box *m_Solid;
|
G4Box *m_Solid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ Assembly::Assembly()
|
|||||||
m_BBoxMax(Vector3f::Zero()),
|
m_BBoxMax(Vector3f::Zero()),
|
||||||
m_ShowBoundingBox(false),
|
m_ShowBoundingBox(false),
|
||||||
m_GroupSelection(true) {
|
m_GroupSelection(true) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Assembly::Assembly(const Assembly ©)
|
Assembly::Assembly(const Assembly ©)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace uLib {
|
|||||||
class Assembly : public ObjectsContext, public TRS {
|
class Assembly : public ObjectsContext, public TRS {
|
||||||
public:
|
public:
|
||||||
uLibTypeMacro(Assembly, ObjectsContext, TRS)
|
uLibTypeMacro(Assembly, ObjectsContext, TRS)
|
||||||
virtual const char *GetClassName() const override { return "Assembly"; }
|
|
||||||
|
|
||||||
Assembly();
|
Assembly();
|
||||||
Assembly(const Assembly ©);
|
Assembly(const Assembly ©);
|
||||||
@@ -113,6 +113,8 @@ private:
|
|||||||
bool m_GroupSelection;
|
bool m_GroupSelection;
|
||||||
bool m_InUpdated = false;
|
bool m_InUpdated = false;
|
||||||
std::map<Object*, Connection> m_ChildConnections;
|
std::map<Object*, Connection> m_ChildConnections;
|
||||||
|
|
||||||
|
ULIB_DECLARE_PROPERTIES(Assembly)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace uLib
|
} // namespace uLib
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "Geometry.h"
|
#include "Geometry.h"
|
||||||
#include "Core/Object.h"
|
#include "Core/Object.h"
|
||||||
#include "Core/Property.h"
|
#include "Core/Property.h"
|
||||||
|
#include "Core/Serializable.h"
|
||||||
#include "Math/Dense.h"
|
#include "Math/Dense.h"
|
||||||
#include "Math/Transform.h"
|
#include "Math/Transform.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -48,16 +49,11 @@ namespace uLib {
|
|||||||
*/
|
*/
|
||||||
class ContainerBox : public TRS {
|
class ContainerBox : public TRS {
|
||||||
|
|
||||||
public:
|
|
||||||
uLibTypeMacro(ContainerBox, TRS)
|
uLibTypeMacro(ContainerBox, TRS)
|
||||||
|
ULIB_SERIALIZE_ACCESS
|
||||||
|
ULIB_DECLARE_PROPERTIES(ContainerBox)
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "ContainerBox"; }
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROPERTIES //
|
|
||||||
|
|
||||||
Vector3f Size;
|
|
||||||
Vector3f Origin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor.
|
* @brief Default constructor.
|
||||||
@@ -67,7 +63,6 @@ public:
|
|||||||
: m_LocalT(this), // BaseClass is Parent of m_LocalTransform
|
: m_LocalT(this), // BaseClass is Parent of m_LocalTransform
|
||||||
Size(1.0f, 1.0f, 1.0f),
|
Size(1.0f, 1.0f, 1.0f),
|
||||||
Origin(0.0f, 0.0f, 0.0f) {
|
Origin(0.0f, 0.0f, 0.0f) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
this->Sync();
|
this->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +74,6 @@ public:
|
|||||||
: m_LocalT(this),
|
: m_LocalT(this),
|
||||||
Size(size),
|
Size(size),
|
||||||
Origin(0.0f, 0.0f, 0.0f) {
|
Origin(0.0f, 0.0f, 0.0f) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
this->Sync();
|
this->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,18 +86,17 @@ public:
|
|||||||
TRS(copy),
|
TRS(copy),
|
||||||
Size(copy.Size),
|
Size(copy.Size),
|
||||||
Origin(copy.Origin) {
|
Origin(copy.Origin) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
this->Sync();
|
this->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* @brief Serialization template for property registration and persistence.
|
// * @brief Serialization template for property registration and persistence.
|
||||||
*/
|
// */
|
||||||
template <class ArchiveT>
|
template <class ArchiveT>
|
||||||
void serialize(ArchiveT & ar, const unsigned int version) {
|
void serialize(ArchiveT & ar, const unsigned int version) {
|
||||||
ar & HRP(Size);
|
ar & HRP(Size);
|
||||||
ar & HRP(Origin);
|
ar & HRP(Origin);
|
||||||
ar & boost::serialization::make_nvp("TRS", boost::serialization::base_object<TRS>(*this));
|
ar & NVP("TRS", boost::serialization::base_object<TRS>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,9 +229,13 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Vector3f Size;
|
||||||
|
Vector3f Origin;
|
||||||
AffineTransform m_LocalT;
|
AffineTransform m_LocalT;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace uLib
|
} // namespace uLib
|
||||||
|
|
||||||
|
|
||||||
#endif // CONTAINERBOX_H
|
#endif // CONTAINERBOX_H
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ namespace uLib {
|
|||||||
*/
|
*/
|
||||||
class Cylinder : public TRS {
|
class Cylinder : public TRS {
|
||||||
|
|
||||||
public:
|
|
||||||
uLibTypeMacro(Cylinder, TRS)
|
uLibTypeMacro(Cylinder, TRS)
|
||||||
|
ULIB_DECLARE_PROPERTIES(Cylinder)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PROPERTIES
|
* @brief PROPERTIES
|
||||||
@@ -51,13 +53,12 @@ public:
|
|||||||
float Height;
|
float Height;
|
||||||
int Axis;
|
int Axis;
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "Cylinder"; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor. Aligns with Y by default.
|
* @brief Default constructor. Aligns with Y by default.
|
||||||
*/
|
*/
|
||||||
Cylinder() : m_LocalT(this), Radius(1.0), Height(1.0), Axis(1) {
|
Cylinder() : m_LocalT(this), Radius(1.0), Height(1.0), Axis(1) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
this->Sync();
|
this->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +67,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Cylinder(float radius, float height, int axis = 1)
|
Cylinder(float radius, float height, int axis = 1)
|
||||||
: m_LocalT(this), Radius(radius), Height(height), Axis(axis) {
|
: m_LocalT(this), Radius(radius), Height(height), Axis(axis) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
this->Sync();
|
this->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Cylinder(const Cylinder ©)
|
Cylinder(const Cylinder ©)
|
||||||
: m_LocalT(this), TRS(copy), Radius(copy.Radius), Height(copy.Height), Axis(copy.Axis) {
|
: m_LocalT(this), TRS(copy), Radius(copy.Radius), Height(copy.Height), Axis(copy.Axis) {
|
||||||
ULIB_ACTIVATE_PROPERTIES(*this);
|
|
||||||
this->Sync();
|
this->Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,10 +83,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <class ArchiveT>
|
template <class ArchiveT>
|
||||||
void serialize(ArchiveT & ar, const unsigned int version) {
|
void serialize(ArchiveT & ar, const unsigned int version) {
|
||||||
ar & boost::serialization::make_nvp("TRS", boost::serialization::base_object<TRS>(*this));
|
|
||||||
ar & HRP(Radius);
|
ar & HRP(Radius);
|
||||||
ar & HRP(Height);
|
ar & HRP(Height);
|
||||||
ar & HRP(Axis);
|
ar & boost::serialization::make_hrp_enum("Axis", Axis, {"X", "Y", "Z"});
|
||||||
|
ar & NVP("TRS", boost::serialization::base_object<TRS>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the radius of the cylinder */
|
/** Sets the radius of the cylinder */
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
uLibTypeMacro(Geometry, Object)
|
uLibTypeMacro(Geometry, Object)
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "Geometry"; }
|
|
||||||
|
|
||||||
virtual void SetParent(Geometry* p) { m_Parent = p; }
|
virtual void SetParent(Geometry* p) { m_Parent = p; }
|
||||||
virtual Geometry* GetParent() const { return m_Parent; }
|
virtual Geometry* GetParent() const { return m_Parent; }
|
||||||
@@ -93,7 +93,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
uLibTypeMacro(LinearGeometry, Geometry)
|
uLibTypeMacro(LinearGeometry, Geometry)
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "LinearGeometry"; }
|
|
||||||
|
|
||||||
virtual bool IsLinear() const override { return true; }
|
virtual bool IsLinear() const override { return true; }
|
||||||
virtual bool IsPure() const override { return true; }
|
virtual bool IsPure() const override { return true; }
|
||||||
@@ -162,7 +162,7 @@ public:
|
|||||||
uLibTypeMacro(CylindricalGeometry, LinearGeometry)
|
uLibTypeMacro(CylindricalGeometry, LinearGeometry)
|
||||||
CylindricalGeometry() {}
|
CylindricalGeometry() {}
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "CylindricalGeometry"; }
|
|
||||||
|
|
||||||
virtual bool IsPure() const override { return false; }
|
virtual bool IsPure() const override { return false; }
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ public:
|
|||||||
uLibTypeMacro(SphericalGeometry, LinearGeometry)
|
uLibTypeMacro(SphericalGeometry, LinearGeometry)
|
||||||
SphericalGeometry() {}
|
SphericalGeometry() {}
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "SphericalGeometry"; }
|
|
||||||
|
|
||||||
virtual bool IsPure() const override { return false; }
|
virtual bool IsPure() const override { return false; }
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ public:
|
|||||||
uLibTypeMacro(ToroidalGeometry, LinearGeometry)
|
uLibTypeMacro(ToroidalGeometry, LinearGeometry)
|
||||||
ToroidalGeometry(float Rtor) : m_Rtor(Rtor) {}
|
ToroidalGeometry(float Rtor) : m_Rtor(Rtor) {}
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "ToroidalGeometry"; }
|
|
||||||
|
|
||||||
virtual bool IsPure() const override { return false; }
|
virtual bool IsPure() const override { return false; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
SUBDIRS = .
|
|
||||||
|
|
||||||
include $(top_srcdir)/Common.am
|
|
||||||
|
|
||||||
library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/Math
|
|
||||||
library_include_HEADERS = ContainerBox.h \
|
|
||||||
Dense.h \
|
|
||||||
Geometry.h \
|
|
||||||
Transform.h \
|
|
||||||
StructuredData.h\
|
|
||||||
StructuredGrid.h\
|
|
||||||
VoxImage.h \
|
|
||||||
VoxRaytracer.h \
|
|
||||||
Utils.h \
|
|
||||||
VoxImageFilter.h\
|
|
||||||
VoxImageFilter.hpp \
|
|
||||||
VoxImageFilterLinear.hpp \
|
|
||||||
VoxImageFilterMedian.hpp \
|
|
||||||
VoxImageFilterABTrim.hpp \
|
|
||||||
VoxImageFilterBilateral.hpp \
|
|
||||||
VoxImageFilterThreshold.hpp \
|
|
||||||
VoxImageFilter2ndStat.hpp \
|
|
||||||
VoxImageFilterCustom.hpp \
|
|
||||||
Accumulator.h \
|
|
||||||
TriangleMesh.h
|
|
||||||
|
|
||||||
|
|
||||||
_MATH_SOURCES = \
|
|
||||||
VoxRaytracer.cpp \
|
|
||||||
StructuredData.cpp \
|
|
||||||
StructuredGrid.cpp \
|
|
||||||
VoxImage.cpp \
|
|
||||||
TriangleMesh.cpp \
|
|
||||||
Dense.cpp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libmutommath.la
|
|
||||||
libmutommath_la_SOURCES = ${_MATH_SOURCES}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ class Polydata : public Object {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual const char * GetClassName() const { return "Polydata"; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class QuadMesh : public TRS
|
|||||||
public:
|
public:
|
||||||
uLibTypeMacro(QuadMesh, TRS)
|
uLibTypeMacro(QuadMesh, TRS)
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "QuadMesh"; }
|
|
||||||
|
|
||||||
void PrintSelf(std::ostream &o);
|
void PrintSelf(std::ostream &o);
|
||||||
|
|
||||||
|
|||||||
@@ -189,8 +189,11 @@ typedef Eigen::Affine3f AffineMatrix;
|
|||||||
|
|
||||||
class TRS : public AffineTransform {
|
class TRS : public AffineTransform {
|
||||||
|
|
||||||
public:
|
|
||||||
uLibTypeMacro(TRS, AffineTransform)
|
uLibTypeMacro(TRS, AffineTransform)
|
||||||
|
ULIB_SERIALIZE_ACCESS
|
||||||
|
// ULIB_DECLARE_PROPERTIES(TRS)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
Vector3f position = Vector3f::Zero();
|
Vector3f position = Vector3f::Zero();
|
||||||
Vector3f rotation = Vector3f::Zero();
|
Vector3f rotation = Vector3f::Zero();
|
||||||
@@ -260,6 +263,7 @@ public:
|
|||||||
ar & HRP(scaling);
|
ar & HRP(scaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AffineMatrix GetAffineMatrix() const {
|
AffineMatrix GetAffineMatrix() const {
|
||||||
AffineMatrix m = AffineMatrix::Identity();
|
AffineMatrix m = AffineMatrix::Identity();
|
||||||
m.translate(position);
|
m.translate(position);
|
||||||
@@ -273,12 +277,26 @@ public:
|
|||||||
Matrix4f GetMatrix() const {
|
Matrix4f GetMatrix() const {
|
||||||
return this->GetAffineMatrix().matrix();
|
return this->GetAffineMatrix().matrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const TRS& trs) {
|
||||||
|
os << trs.position << " " << trs.rotation << " " << trs.scaling;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::istream& operator>>(std::istream& is, TRS& trs) {
|
||||||
|
is >> trs.position >> trs.rotation >> trs.scaling;
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
} // uLib
|
} // uLib
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class TriangleMesh : public TRS
|
|||||||
public:
|
public:
|
||||||
uLibTypeMacro(TriangleMesh, TRS)
|
uLibTypeMacro(TriangleMesh, TRS)
|
||||||
|
|
||||||
virtual const char * GetClassName() const override { return "TriangleMesh"; }
|
|
||||||
|
|
||||||
void PrintSelf(std::ostream &o);
|
void PrintSelf(std::ostream &o);
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Abstract {
|
|||||||
class VoxImage : public uLib::StructuredGrid {
|
class VoxImage : public uLib::StructuredGrid {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual const char * GetClassName() const { return "VoxImage"; }
|
|
||||||
|
|
||||||
typedef uLib::StructuredGrid BaseClass;
|
typedef uLib::StructuredGrid BaseClass;
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class VoxImageFilter : public Abstract::VoxImageFilter, public Object {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual const char * GetClassName() const { return "VoxImageFilter"; }
|
|
||||||
|
|
||||||
VoxImageFilter(const Vector3i &size);
|
VoxImageFilter(const Vector3i &size);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class vtkObjectsContext; // forward
|
|||||||
*/
|
*/
|
||||||
class Assembly : public Puppet {
|
class Assembly : public Puppet {
|
||||||
public:
|
public:
|
||||||
virtual const char *GetClassName() const override { return "Vtk.Assembly"; }
|
uLibTypeMacro(Assembly, Puppet)
|
||||||
|
|
||||||
Assembly(uLib::Assembly *content);
|
Assembly(uLib::Assembly *content);
|
||||||
virtual ~Assembly();
|
virtual ~Assembly();
|
||||||
|
|||||||
@@ -603,6 +603,8 @@ void Puppet::ConnectInteractor(vtkRenderWindowInteractor *interactor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------ //
|
// ------------------------------------------------------ //
|
||||||
// SERIALIZE DISPLAY PROPERTIES
|
// SERIALIZE DISPLAY PROPERTIES
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
#include "Vtk/Math/vtkCylinder.h"
|
#include "Vtk/Math/vtkCylinder.h"
|
||||||
#include "Vtk/Math/vtkAssembly.h"
|
#include "Vtk/Math/vtkAssembly.h"
|
||||||
#include "Vtk/Math/vtkVoxImage.h"
|
#include "Vtk/Math/vtkVoxImage.h"
|
||||||
|
|
||||||
#include "HEP/Detectors/vtkDetectorChamber.h"
|
#include "HEP/Detectors/vtkDetectorChamber.h"
|
||||||
|
#include "HEP/Geant/vtkBoxSolid.h"
|
||||||
|
|
||||||
#include <vtkAssembly.h>
|
#include <vtkAssembly.h>
|
||||||
#include <vtkPropCollection.h>
|
#include <vtkPropCollection.h>
|
||||||
@@ -127,6 +129,9 @@ Puppet* vtkObjectsContext::CreatePuppet(uLib::Object* obj) {
|
|||||||
} else if (auto* assembly = dynamic_cast<uLib::Assembly*>(obj)) {
|
} else if (auto* assembly = dynamic_cast<uLib::Assembly*>(obj)) {
|
||||||
return new Assembly(assembly);
|
return new Assembly(assembly);
|
||||||
}
|
}
|
||||||
|
else if (auto* box = dynamic_cast<uLib::Geant::BoxSolid*>(obj)) {
|
||||||
|
return new vtkBoxSolid(box);
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback if we don't know the exact class but it might be a context itself
|
// Fallback if we don't know the exact class but it might be a context itself
|
||||||
if (auto subCtx = dynamic_cast<uLib::ObjectsContext*>(obj)) {
|
if (auto subCtx = dynamic_cast<uLib::ObjectsContext*>(obj)) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Vtk {
|
|||||||
*/
|
*/
|
||||||
class vtkObjectsContext : public Puppet {
|
class vtkObjectsContext : public Puppet {
|
||||||
public:
|
public:
|
||||||
virtual const char* GetClassName() const override { return "vtkObjectsContext"; }
|
uLibTypeMacro(vtkObjectsContext, Puppet)
|
||||||
vtkObjectsContext(uLib::ObjectsContext *context);
|
vtkObjectsContext(uLib::ObjectsContext *context);
|
||||||
virtual ~vtkObjectsContext();
|
virtual ~vtkObjectsContext();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user