First time here? Check out the Help page!
1 | initial version |
First of all, nothing in this question applies to the Ruby API so if you are only writing measures you can stop reading this question now :-) This is only of interest to people developing the C++ portions of OpenStudio.
OpenStudio does use the PIMPL idiom for all of the ModelObject classes. There are many advantages to PIMPL but OpenStudio does not make use of many of them. PIMPL was chosen for OpenStudio mainly for properties of the SWIG wrappers, it was the best way to get ModelObjects that "acted right" in Ruby. Each ModelObject has three C++ source files associated with it:
The Cpp file implementing FooObject and FooObject_Impl needs to include both headers. Another file that simply uses FooObject can get away with only including FooObject.hpp. However, any code that needs to cast a ModelObject to a FooObject needs to include both FooObject.hpp and FooObject_Impl.hpp. This casting ends up being fairly pervasive, e.g. model.getModelObjects<FooObject>()
, so the Impl headers are included in more files than I would like. We could work around this by adding explicit cast methods for each type like those generated in Ruby, e.g. model.getFooObjects()
, but we have not bitten that off.
2 | No.2 Revision |
First of all, nothing in this question applies to the Ruby API so if you are only writing measures you can stop reading this question now :-) This is only of interest to people developing the C++ portions of OpenStudio.
OpenStudio does use the PIMPL idiom for all of the ModelObject classes. There are many advantages to PIMPL but OpenStudio does not make use of many of them. PIMPL was chosen for OpenStudio mainly for properties of the SWIG wrappers, it was the best way to get ModelObjects that "acted right" in Ruby. Each ModelObject has three C++ source files associated with it:
FooObject.hpp
- the public headerFooObject_Impl.hpp
- the private headerFooObject.cpp
- implementation of the public and private classesThe Cpp file implementing FooObject FooObject
and FooObject_Impl FooObject_Impl
needs to include both headers. headers.
Another file that simply uses FooObject FooObject
can get away with only including FooObject.hpp. FooObject.hpp
. However, any code that needs to cast a ModelObject ModelObject
to a FooObject FooObject
needs to include both FooObject.hpp FooObject.hpp
and FooObject_Impl.hpp. FooObject_Impl.hpp
.
This casting ends up being fairly pervasive, e.g. model.getModelObjects<FooObject>()
, so the Impl headers are included in more files than I would like. We could work around this by adding explicit cast methods for each type like those generated in Ruby, e.g. model.getFooObjects()
, but we have not bitten that off.