hecl
High-Level Extensible Combiner Language and Resource Database
HECLDatabase.hpp
1 #ifndef HECLDATABASE_HPP
2 #define HECLDATABASE_HPP
3 
4 #include <iterator>
5 #include <string>
6 #include <functional>
7 #include <vector>
8 #include <map>
9 #include <unordered_map>
10 #include <memory>
11 #include <atomic>
12 #include <stdexcept>
13 #include <stdint.h>
14 
15 #include <Athena/IStreamReader.hpp>
16 
17 #include "HECL.hpp"
18 
19 namespace HECL
20 {
21 namespace Database
22 {
23 
28 {
29 public:
30  struct Node
31  {
32  enum
33  {
34  NODE_DATA,
35  NODE_GROUP
36  } type;
37  SystemString path;
38  class ObjectBase* projectObj;
39  Node* sub;
40  Node* next;
41  };
42 private:
43  friend class Project;
44  std::vector<Node> m_nodes;
45 public:
46  const Node* getRootNode() const {return &m_nodes[0];}
47 };
48 
55 class IDataSpec
56 {
57 public:
59  {
60  SystemString srcpath;
61  ProjectPath subpath;
62  };
63  virtual bool canExtract(const ExtractPassInfo& info) {(void)info;return false;}
64  virtual void doExtract(const ExtractPassInfo& info) {(void)info;}
65 
67  {
68  PackageDepsgraph& depsgraph;
69  ProjectPath subpath;
70  };
71  virtual bool canPackage(const PackagePassInfo& info) {(void)info;return false;}
72  virtual void doPackage(const PackagePassInfo& info) {(void)info;}
73 };
74 
79 {
80  SystemString name;
81  SystemString desc;
82  std::function<IDataSpec*(void)> factory;
83 };
84 extern const HECL::Database::DataSpecEntry DATA_SPEC_REGISTRY[];
85 
96 {
97  friend class Project;
98  SystemString m_path;
99 protected:
100 
105  {
106  DE_NONE,
109  };
110 
115  {
116  DP_NONE,
120  };
121 
122  typedef std::function<void(const void* data, size_t len)> FDataAppender;
123 
135  virtual bool _cookObject(FDataAppender dataAppender,
136  DataEndianness endianness, DataPlatform platform)
137  {(void)dataAppender;(void)endianness;(void)platform;return true;}
138 
139  typedef std::function<void(ObjectBase*)> FDepAdder;
140 
149  virtual void _gatherDeps(FDepAdder depAdder)
150  {(void)depAdder;}
151 
152 public:
153  ObjectBase(const SystemString& path)
154  : m_path(path) {}
155 
156  inline const SystemString& getPath() const {return m_path;}
157 
158 };
159 
160 
168 class Project
169 {
170 public:
171  typedef std::vector<std::pair<const DataSpecEntry&, bool>> CompiledSpecs;
172 private:
173  ProjectRootPath m_rootPath;
174  CompiledSpecs m_compiledSpecs;
175 public:
176  Project(const HECL::ProjectRootPath& rootPath);
177 
185  {
186  SystemString m_filepath;
187  std::vector<std::string> m_lines;
188  FILE* m_lockedFile = NULL;
189  public:
190  ConfigFile(const Project& project, const SystemString& name);
191  const std::vector<std::string>& lockAndRead();
192  void addLine(const std::string& line);
193  void removeLine(const std::string& refLine);
194  bool checkForLine(const std::string& refLine);
195  void unlockAndDiscard();
196  void unlockAndCommit();
197  };
198  ConfigFile m_specs;
199  ConfigFile m_paths;
200  ConfigFile m_groups;
201 
208  class IndexFile
209  {
210  SystemString m_filepath;
211  const Project& m_project;
212  size_t m_maxPathLen = 0;
213  size_t m_onlyUpdatedMaxPathLen = 0;
214  FILE* m_lockedFile = NULL;
215  public:
216  class Entry
217  {
218  friend class IndexFile;
219  ProjectPath m_path;
220  HECL::Time m_lastModtime;
221  bool m_updated = false;
222  Entry(const ProjectPath& path, const HECL::Time& lastModtime)
223  : m_path(path), m_lastModtime(lastModtime) {}
224  Entry(const ProjectPath& path);
225  };
226  private:
227  size_t m_updatedCount = 0;
228  std::vector<Entry> m_entryStore;
229  std::unordered_map<ProjectPath, Entry*> m_entryLookup;
230  public:
231  IndexFile(const Project& project);
232  const std::vector<Entry>& lockAndRead();
233  const std::vector<ProjectPath*> getChangedPaths();
234  void addOrUpdatePath(const ProjectPath& path);
235  void unlockAndDiscard();
236  void unlockAndCommit(bool onlyUpdated=false);
237  };
238  IndexFile m_index;
239 
248  class PackageException : public std::runtime_error {};
249 
255  enum Cost
256  {
257  C_NONE,
258  C_LIGHT,
259  C_MEDIUM,
260  C_HEAVY
261  };
262 
269  void registerLogger(HECL::FLogger logger);
270 
278  inline const ProjectRootPath& getProjectRootPath() const {return m_rootPath;}
279 
287  bool addPaths(const std::vector<ProjectPath>& paths);
288 
298  bool removePaths(const std::vector<ProjectPath>& paths, bool recursive=false);
299 
314  bool addGroup(const ProjectPath& path);
315 
321  bool removeGroup(const ProjectPath& path);
322 
327  inline const CompiledSpecs& getDataSpecs() {return m_compiledSpecs;}
328 
334  bool enableDataSpecs(const std::vector<SystemString>& specs);
335 
341  bool disableDataSpecs(const std::vector<SystemString>& specs);
342 
354  bool cookPath(const ProjectPath& path,
355  std::function<void(SystemString&, Cost, unsigned)> feedbackCb,
356  bool recursive=false);
357 
368  void interruptCook();
369 
379  bool cleanPath(const ProjectPath& path, bool recursive=false);
380 
387 
388 };
389 
390 }
391 }
392 
393 #endif // HECLDATABASE_HPP
bool removeGroup(const ProjectPath &path)
Unregister a working sub-directory as a dependency group.
void registerLogger(HECL::FLogger logger)
Register an optional callback to report log-messages using.
Subclassed by dataspec entries to manage per-game aspects of the data pipeline.
Definition: HECLDatabase.hpp:55
bool cleanPath(const ProjectPath &path, bool recursive=false)
Delete cooked objects for directory.
bool addGroup(const ProjectPath &path)
Register a working sub-directory as a Dependency Group.
const CompiledSpecs & getDataSpecs()
Return map populated with dataspecs targetable by this project interface.
Definition: HECLDatabase.hpp:327
bool enableDataSpecs(const std::vector< SystemString > &specs)
Enable persistent user preference for particular spec string(s)
Definition: HECLDatabase.hpp:216
Definition: HECLDatabase.hpp:108
virtual void _gatherDeps(FDepAdder depAdder)
Optional private method implemented by CProjectObject subclasses to resolve dependencies.
Definition: HECLDatabase.hpp:149
Definition: HECLDatabase.hpp:30
Definition: HECLDatabase.hpp:119
Base object to subclass for integrating with key project operations.
Definition: HECLDatabase.hpp:95
IDataSpec registry entry.
Definition: HECLDatabase.hpp:78
Nodegraph class for gathering dependency-resolved objects for packaging.
Definition: HECLDatabase.hpp:27
void interruptCook()
Interrupts a cook in progress (call from SIGINT handler)
Definition: HECLDatabase.hpp:118
Cost
A rough description of how 'expensive' a given cook operation is.
Definition: HECLDatabase.hpp:255
Main project interface.
Definition: HECLDatabase.hpp:168
PackageDepsgraph buildPackageDepsgraph(const ProjectPath &path)
Constructs a full depsgraph of the project-subpath provided.
Timestamp representation used for comparing modtimes of cooked resources.
Definition: HECL.hpp:280
DataEndianness
Byte-order of target system.
Definition: HECLDatabase.hpp:104
Special ProjectRootPath subclass for opening HECLDatabase::IProject instances.
Definition: HECL.hpp:425
Internal packagePath() exception.
Definition: HECLDatabase.hpp:248
Definition: HECLDatabase.hpp:107
const ProjectRootPath & getProjectRootPath() const
Get the path of the project's root-directory.
Definition: HECLDatabase.hpp:278
Definition: HECLDatabase.hpp:117
Definition: HECLDatabase.hpp:58
Definition: HECL.hpp:24
Configuration file handle.
Definition: HECLDatabase.hpp:184
Definition: HECLDatabase.hpp:66
bool removePaths(const std::vector< ProjectPath > &paths, bool recursive=false)
Remove a given file or file-pattern from the database.
bool disableDataSpecs(const std::vector< SystemString > &specs)
Disable persistent user preference for particular spec string(s)
Canonicalized project path representation using POSIX conventions.
Definition: HECL.hpp:310
bool cookPath(const ProjectPath &path, std::function< void(SystemString &, Cost, unsigned)> feedbackCb, bool recursive=false)
Begin cook process for specified directory.
DataPlatform
Data-formats of target system.
Definition: HECLDatabase.hpp:114
virtual bool _cookObject(FDataAppender dataAppender, DataEndianness endianness, DataPlatform platform)
Optional private method implemented by CProjectObject subclasses to cook objects. ...
Definition: HECLDatabase.hpp:135
Index file handle.
Definition: HECLDatabase.hpp:208
bool addPaths(const std::vector< ProjectPath > &paths)
Add given file(s) to the database.