loot / libloot

A C++ library for accessing LOOT's metadata and sorting functionality.
GNU General Public License v3.0
32 stars 12 forks source link

Figure out how to expose metadata interfaces without exposing implementation #13

Closed Ortham closed 6 years ago

Ortham commented 6 years ago

The API's handling of metadata structures is not ideal, because extending them with new fields is not a breaking change for the YAML metadata but is a breaking change for the API.

One option is to hide implementation detail using the pimpl pattern, another is to only expose metadata in serialised form and providing a schema to define the serialisation.

While the metadata is written in YAML because it's a good format for humans writing structured data, it's a relatively poor format for data transfer. There are also few if any good YAML schema parsers. I'm currently evaluating the following:

Ortham commented 6 years ago

Its worth noting that the only methods that aren't constructors or simple field getters/setters that are exposed by the metadata classes and actually used in LOOT are:

So having those classes is almost completely unnecessary, the above could easily be free functions.

Ortham commented 6 years ago

The YAML de/serialisation headers are no longer available in the include directory, as of 4fc75979ec0d1cf68e635cae138d91ae96a96c6e, as LOOT now uses independent JSON de/serialisation code.

FlatBuffers and Cap'n Proto turned out to be unsuitable as their classes don't own the data they deserialise, so they're not useful for storing an internal representation. Protocol Buffers doesn't have this problem, but is a very large dependency.

At this point it looks like serialisation as an interface in general is unsuitable as it just makes using the API more difficult for clients.

Ortham commented 6 years ago

After further thought I'm not going to go ahead with pimpl-ing the API's metadata classes, because every metadata syntax update so far has involved breaking changes anyway, and it's not worth me doing the work now for a hypothetical improvement in a scenario that may never occur, I might as well solve the problem when it comes up.