Project Layout
Pagoda tries to follow the Pitchfork Layout Model (PFL) as closely as possible.
The authors succinctly describe PFL as follows:
PFL a convention for laying out source, build, and resource files in a filesystem to aide in uniformity, tooling, understandability, and compartmentalization.
It's a very thought out layout that tries to achieve a more standard way of structuring a C++ source code. To this end, and in the interest of keeping things as standard as possible with other open source projects, this page describes the project layout for pagoda.
Top Level Layout
From the layout described in PCL, pagoda uses the following:
pagoda/
build/
include/
pagoda/
src/
pagoda/
bin/
tests/
external/
docs/
We will start by describing the simplest directories first.
Build Directory
The purpose of the build is to contain ephemeral build results and should not be checked into the version control system. According to PFL multiple subdirectories are allowed, each reflecting a different build configuration (e.g., Release or Debug).
Tests Directory
The purpose of the tests directory is to contain all source code files used to compile (non-unit) tests. More specifically, this directory contains regression tests for both pagoda graph files and pgscript scripts.
To allow pagoda to be embedded in other projects, the compilation of the tests in this directory should be automatically disabled.
Unit tests are placed alongside the respective unit they are testing. For
example, if we have a class in pagoda/src/module/a_class.cpp
its test should
be placed in pagoda/src/module/a_class.test.cpp
. The advantage being that,
while writing pagoda's source code, it should be easier to navigate between
source and test code and to understand which compilation units have unit tests
or not.
External Directory
The purpose of the external directory is to contain all embeddable projects that are to be built as a part of pagoda. Each subdirectory should be respective to a different project.
Currently, the only embeddable dependency in pagoda is the google test. Because it is set as a git sub-module, its subdirectory within the exteral directory is auto-populated.
Include Directory
The purpose of the include directory is to hold pagoda's public headers which are meant to be used by clients of the pagoda library.
Consumers of pagoda's library should only be pointed to this directory as a
source of include files, preventing users from being able to #include
files
that are inside the source directory.
The file structure within the include directory follows the exact same structure as the src directory.
Src Directory
The purpose the src directory is to contain all source code files to build pagoda executable binary and library.
The PFL doesn't shed a lot of light into how the split between library code and
executable code should be achieved. Furthermore, because pagoda's main
codebase lies in its library and it is still not clear how many executables
this project will have, the current choice of splitting is to have a
src/pagoda/
and include/pagoda/
directories for the library and a
src/bin/
directory for the executables. At this stage, it is not prescribed
how the source code for each binary shall be structure within this directory.
C++ namespaces should be reflected in the file structure of both the src
and include directories. For example the class pagoda::geometry::Geometry
should have its c++ file in pagoda/src/pagoda/geometry/Geometry.cpp
and its
header file in pagoda/include/pagoda/geometry/Geometry.h
(assuming it's a
public header).
Namespace Layout
Pagoda's library has several components that should be properly organised to allow a better and faster development. Because the namespace structure dictates the file layout, it is more convenient to describe the namespaces and their structure.
pagoda::
common::
debug::
exception::
fs::
instrument::
math::
objects::
graph::
io::
geometry::
core::
io::
algorithms::
operations::
pgscript::
value::
parser::
intermediate::
interpreter::
dynamic::
binding::
common namespace
The common namespace contains code that, as the name implies, is common to all of pagoda. Within it, there are namespaces with code to help in debugging (e.g., assertions, logging), the base of the exception system, generic file system handling and code for instrumenting pagoda itself (e.g., profilers and statistics).
math namespace
The math namespace contains mathematical functions and methods that are not provided by other libraries (currently, pagoda is only using boost libraries). Whenever possible, it should be better reusing maths code that is provided by specific libraries. Pagoda doesn't want to reinvent the mathematical wheel.
object namespace
The object namespace is meat to contain the code related to the procedural objects system. As described in its documentation, this is an entity composed system.
graph namespace
The graph namespace contains code that allows defining the procedural graphs, its rules and their posterior execution. The execution code for the core node types, along with the extension points, should also reside within this name space.
Code for loading and saving graphs (to disk or elsewhere) should be contained in the pagoda::graph::io namespace.
geometry namespace
The geometry namespace contains code for geometry and topology representations in its core namespace. In the io namespace provides methods for reading and writing geometries to file or elsewhere.
pgscript namespace
The pgscript namespace contains code for the pgscript scripting language.
dynamic namepsace
The dynamic namespace contains code that serves as dynamic bindings between C++ and either pgscript or parameters in graph or operations.