VTK  9.3.1
vtkObjectFactory.cmake
Go to the documentation of this file.
1 #[==[
2 @file vtkObjectFactory.cmake
3 
4 In VTK, certain classes can have what are called "implementations". When the
5 base class is requested, it instead looks into a list of available
6 implementations. One of the implementations is then constructed and returned
7 instead.
8 
9 For instance, there is a `vtkRenderWindow` class in VTK. When this is
10 constructed, it instead actually returns a window for the X window system,
11 Cocoa, or Win32 depending on what is available.
12 
13 VTK's implementation utilizes the
14 [autoinit](https://docs.vtk.org/en/latest/api/cmake/ModuleSystem.html#autoinit)
15 logic of the
16 module system. A module which contains an object factory must declare itself as
17 `IMPLEMENTABLE` and modules which contain an implementation of an object
18 factory must claim that they `IMPLEMENTS` modules containing those base object
19 factories (a module may contain the object factory and an implementation; it
20 then says that it `IMPLEMENTS` itself).
21 #]==]
22 
23 set(_vtkObjectFactory_source_dir "${CMAKE_CURRENT_LIST_DIR}")
24 
25 #[==[
26 @brief Declare a factory override
27 
28 Declare that a class in this module (the implementation) is an `OVERRIDE` for a
29 base class.
30 
31 ~~~
32 vtk_object_factory_declare(
33  BASE <base>
34  OVERRIDE <implementation>)
35 ~~~
36 #]==]
37 function (vtk_object_factory_declare)
38  cmake_parse_arguments(PARSE_ARGV 0 _vtk_object_factory_declare
39  ""
40  "BASE;OVERRIDE"
41  "")
42 
43  if (_vtk_object_factory_declare_UNPARSED_ARGUMENTS)
44  message(FATAL_ERROR
45  "Unparsed arguments for vtk_object_factory_declare: "
46  "${_vtk_object_factory_declare_UNPARSED_ARGUMENTS}")
47  endif ()
48 
49  if (NOT DEFINED _vtk_object_factory_declare_BASE)
50  message(FATAL_ERROR
51  "The `BASE` argument is required.")
52  endif ()
53 
54  if (NOT DEFINED _vtk_object_factory_declare_OVERRIDE)
55  message(FATAL_ERROR
56  "The `OVERRIDE` argument is required.")
57  endif ()
58 
59  set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND
60  PROPERTY
61  _vtk_object_factory_overrides "${_vtk_object_factory_declare_OVERRIDE}")
62  set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND
63  PROPERTY
64  "_vtk_object_factory_override_${_vtk_object_factory_declare_OVERRIDE}" "${_vtk_object_factory_declare_BASE}")
65 endfunction ()
66 
67 #[==[
68 @brief Generate source for overrides in a module
69 
70 A module may only have a single declaration of all its object factory
71 implementations. This function generates the source for all of the overrides
72 declared using @ref vtk_object_factory_declare.
73 
74 ~~~
75 vtk_object_factory_configure(
76  SOURCE_FILE <variable>
77  [HEADER_FILE <variable>]
78  [EXPORT_MACRO <macro>]
79  [INITIAL_CODE <code>]
80  [EXTRA_INCLUDES <include>...])
81 ~~~
82 
83  - `SOURCE_FILE`: (Required) A variable to set to the path to generated source
84  file.
85  - `HEADER_FILE`: (Recommended) A variable to set to the path to generated
86  header file. This should not be treated as a public header.
87  - `EXPORT_MACRO`: (Recommended) The export macro to add to the generated
88  class.
89  - `INITIAL_CODE`: C++ code to run when the object factory is initialized.
90  - `EXTRA_INCLUDES`: A list of headers to include. The header names need to
91  include the `<>` or `""` quoting.
92 #]==]
93 function (vtk_object_factory_configure)
94  if (NOT DEFINED _vtk_build_module)
95  message(FATAL_ERROR
96  "The `vtk_object_factory_configure` function needs to be run within a module context.")
97  endif ()
98 
99  cmake_parse_arguments(PARSE_ARGV 0 _vtk_object_factory_configure
100  ""
101  "SOURCE_FILE;HEADER_FILE;INITIAL_CODE;EXPORT_MACRO"
102  "EXTRA_INCLUDES")
103 
104  if (_vtk_object_factory_configure_UNPARSED_ARGUMENTS)
105  message(FATAL_ERROR
106  "Unparsed arguments for vtk_object_factory_configure: "
107  "${_vtk_object_factory_configure_UNPARSED_ARGUMENTS}")
108  endif ()
109 
110  get_property(_vtk_object_factory_done
111  GLOBAL
112  PROPERTY "_vtk_object_factory_${_vtk_build_module}"
113  SET)
114  if (_vtk_object_factory_done)
115  message(FATAL_ERROR
116  "An object factory has already been created for ${_vtk_build_module}.")
117  else ()
118  set_property(GLOBAL
119  PROPERTY
120  "_vtk_object_factory_${_vtk_build_module}" 1)
121  endif ()
122 
123  get_property(_vtk_object_factory_overrides
124  DIRECTORY
125  PROPERTY _vtk_object_factory_overrides)
126 
127  if (NOT _vtk_object_factory_overrides)
128  message(WARNING
129  "The ${_vtk_build_module} is generating an object factory, but does not have any declared overrides.")
130  endif ()
131 
132  set(_vtk_object_factory_doc
133  "Override for ${_vtk_build_module} module")
134 
135  set(_vtk_object_factory_includes "")
136  set(_vtk_object_factory_functions "")
137  set(_vtk_object_factory_calls "")
138 
139  foreach (_vtk_object_factory_extra_include IN LISTS _vtk_object_factory_configure_EXTRA_INCLUDES)
140  string(APPEND _vtk_object_factory_includes
141  "#include ${_vtk_object_factory_extra_include}\n")
142  endforeach ()
143 
144  foreach (_vtk_object_factory_override IN LISTS _vtk_object_factory_overrides)
145  get_property(_vtk_object_factory_base
146  DIRECTORY
147  PROPERTY "_vtk_object_factory_override_${_vtk_object_factory_override}")
148  string(APPEND _vtk_object_factory_includes
149  "#include \"${_vtk_object_factory_override}.h\"\n")
150  string(APPEND _vtk_object_factory_functions
151  "VTK_CREATE_CREATE_FUNCTION(${_vtk_object_factory_override})\n")
152  string(APPEND _vtk_object_factory_calls
153  "this->RegisterOverride(\"${_vtk_object_factory_base}\", \"${_vtk_object_factory_override}\", \"${_vtk_object_factory_doc}\", 1, vtkObjectFactoryCreate${_vtk_object_factory_override});\n")
154  endforeach ()
155 
156  get_property(_vtk_object_factory_library_name GLOBAL
157  PROPERTY "_vtk_module_${_vtk_build_module}_library_name")
158 
159  set(_vtk_object_factory_overrides_header
160  "${CMAKE_CURRENT_BINARY_DIR}/${_vtk_object_factory_library_name}ObjectFactory.h")
161  set(_vtk_object_factory_overrides_source
162  "${CMAKE_CURRENT_BINARY_DIR}/${_vtk_object_factory_library_name}ObjectFactory.cxx")
163 
164  configure_file(
165  "${_vtkObjectFactory_source_dir}/vtkObjectFactory.h.in"
166  "${_vtk_object_factory_overrides_header}"
167  @ONLY)
168  configure_file(
169  "${_vtkObjectFactory_source_dir}/vtkObjectFactory.cxx.in"
170  "${_vtk_object_factory_overrides_source}"
171  @ONLY)
172 
173  if (_vtk_object_factory_configure_HEADER_FILE)
174  set("${_vtk_object_factory_configure_HEADER_FILE}"
175  "${_vtk_object_factory_overrides_header}"
176  PARENT_SCOPE)
177  endif ()
178 
179  set("${_vtk_object_factory_configure_SOURCE_FILE}"
180  "${_vtk_object_factory_overrides_source}"
181  PARENT_SCOPE)
182 endfunction ()
create a window for renderers to draw into
abstract base class for vtkObjectFactories