In my opinion, ObjectIdentifier has a great potential, because I believe that internally FreeCAD references should be less dependent on OCCT generated shapes. I believe we should have more named references (or tagged with uuid) directly between "native types".
Regardless of if you agree or not with that, I would like to work on ObjectIdentifier. It provides a mechanism for referencing objects by "name". But not only objects, but individual values (member variables) on those. For example, theoretically, you can reference the "y" coordinate of the "starting point" of some "line segment" in a "sketch". I imagine a path like:
- sketch.geometries.TheLineINamed.Start.y
After the hard work of giants, it is now much easier to see the big picture. By no means I want to criticize those people or their work. Let me mention some simple things that I would like to improve:
Hard coded polimorphism in ObjectIdentifier::Component
Many classes in FreeCAD have their behaviour specified through the use of enum. This enum specifies the "type of object". All over the place, the logic of those classes get too complicated because things start to have different meaning according to the "type of object". One example is the Sketcher::Constraint. Many methods need engage in a very complicated logic to determine the meaning of the member variables, because the real meaning depends on the "constraint type". Just take a look on the size of ConstraintPy::PyInit(). There are 30 "else if" on it.
To start with something easier, I would like to specialize App::ObjectIdentifier::Component. From the documentation:
Inside Component we have:A component is a part of a Path object, and is used to either name a property or a field within a property. A component can be either a single entry, and array, or a map to other sub-fields.
Code: Select all
static Component SimpleComponent(const char * _component);
static Component SimpleComponent(const String & _component);
static Component SimpleComponent(String &&_component);
static Component ArrayComponent(int _index);
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step=1);
static Component MapComponent(const String &_key);
static Component MapComponent(String &&_key);
Code: Select all
bool isSimple() const { return type == SIMPLE; }
bool isMap() const { return type == MAP; }
bool isArray() const { return type == ARRAY; }
bool isRange() const { return type == RANGE; }
Code: Select all
static Component SimpleComponent(const char * _component)
{return Component::SimpleComponent(_component);}
static Component SimpleComponent(const String & _component)
{return Component::SimpleComponent(_component);}
static Component SimpleComponent(String &&_component)
{return Component::SimpleComponent(std::move(_component));}
static Component SimpleComponent(const std::string _component)
{return Component::SimpleComponent(_component.c_str());}
static Component ArrayComponent(int _index)
{return Component::ArrayComponent(_index); }
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step=1)
{return Component::RangeComponent(_begin,_end,_step);}
static Component MapComponent(const String &_key)
{return Component::MapComponent(_key);}
static Component MapComponent(String &&_key)
{return Component::MapComponent(_key);}
A small price to pay is that ObjectIdentifier cannot hold a std::vector<Component>. It will probably have to hold some std::vector<std::unique_ptr<Component>>, instead.
Hard coded polimorphism in ObjectIdentifier
Each ObjectIdentifier identifies a specific type of data. So, it should be specialized to avoid boost::any and, instead access the number, vector, property, etc.
Not only we would avoid lots of castings, but we can specify the expected type in many places. For example:
- This is an identifier for a number; or
- I expect an identifier for a number.
Anyone interested?
I can do all the conding... I just want people interested in the idea, to discuss stuff with... or to guide me and point out things I am not aware... or suggest approaches...