14 #include <rapidjson/filereadstream.h>
15 #include <rapidjson/stringbuffer.h>
17 #define PRETTY_JSON_OUTPUT 0
18 #if PRETTY_JSON_OUTPUT == 1
19 #include "rapidjson/prettywriter.h"
21 #include "rapidjson/writer.h"
28 ProjectManager* ProjectManager::inst =
nullptr;
32 ProjectManager::ProjectManager() : m_project_status(ProjectStatus::NONE)
46 if (m_serializer.find(tagname) == m_serializer.end())
47 m_serializer[tagname] = serializer;
50 log_warning(
"project_manager",
"serializer '{}' already registered.", tagname);
56 auto it = m_serializer.find(tagname);
57 if (it != m_serializer.end())
58 m_serializer.erase(it);
63 auto it = m_filename.find(tagname);
64 if (it == m_filename.end())
73 if (!std::filesystem::exists(m_proj_dir))
75 log_warning(
"project_manager",
"cannot open project '{}', path doesn't exist.", path);
80 m_project_status = ProjectStatus::OPENED;
100 if (std::filesystem::exists(m_proj_dir))
102 bool success = std::filesystem::create_directory(m_proj_dir, errCode);
105 log_warning(
"project_manager",
"cannot create directory '{}': '{}'", m_proj_dir.string(), errCode.message());
112 std::filesystem::create_directory(m_proj_dir.
get_filename(
"py"));
114 return serialize_to_projectfile(
false);
119 if (m_proj_dir.empty())
121 return std::filesystem::remove_all(m_proj_dir);
126 m_project_status = stat;
131 return m_project_status;
136 m_gatelib_path = glpath;
144 m_netlist_save = netlist;
147 m_gatelib_path = gl->
get_path().string();
156 if (!serialize_external(shadow))
159 return serialize_to_projectfile(shadow);
164 std::filesystem::path filename(m_proj_dir);
165 filename.append(m_netlist_file);
166 return filename.string();
171 return m_netlist_load;
176 std::filesystem::path projFilePath(m_proj_dir);
179 FILE* fp = fopen(projFilePath.string().c_str(),
"r");
184 rapidjson::FileReadStream frs(fp, buffer,
sizeof(buffer));
185 rapidjson::Document doc;
186 doc.ParseStream<0, rapidjson::UTF8<>, rapidjson::FileReadStream>(frs);
189 if (doc.HasMember(
"netlist"))
191 rapidjson::Value::MemberIterator netlistMember = doc.FindMember(
"netlist");
192 std::string netlistFilename = netlistMember->value.GetString();
196 netlistFilename.erase(0, n);
197 netlistMember->value.SetString(netlistFilename.c_str(), doc.GetAllocator());
199 std::ofstream of(projFilePath);
203 rapidjson::StringBuffer strbuf;
204 #if PRETTY_JSON_OUTPUT == 1
205 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
207 rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
210 of << strbuf.GetString();
216 bool ProjectManager::deserialize()
218 std::filesystem::path projFilePath(m_proj_dir);
221 FILE* fp = fopen(projFilePath.string().c_str(),
"r");
224 log_error(
"project_manager",
"cannot open project file '{}'.", projFilePath.string());
229 rapidjson::FileReadStream frs(fp, buffer,
sizeof(buffer));
230 rapidjson::Document doc;
231 doc.ParseStream<0, rapidjson::UTF8<>, rapidjson::FileReadStream>(frs);
234 if (doc.HasMember(
"gate_library"))
236 m_gatelib_path = doc[
"gate_library"].GetString();
237 std::filesystem::path gatelibPath(m_gatelib_path);
238 if (gatelibPath.is_relative())
239 gatelibPath = m_proj_dir / gatelibPath;
241 if (doc.HasMember(
"netlist"))
243 m_netlist_file = doc[
"netlist"].GetString();
244 std::filesystem::path netlistPath(m_proj_dir);
245 netlistPath.append(m_netlist_file);
249 log_error(
"project_manager",
"cannot load netlist {}.", netlistPath.string());
255 log_error(
"project_manager",
"no 'netlist' token found in project file {}.", projFilePath.string());
261 log_error(
"netlist",
"'gate_library' token not found in project file '{}'.", projFilePath.string());
266 if (doc.HasMember(
"serializer"))
268 for (
auto it = doc[
"serializer"].MemberBegin(); it != doc[
"serializer"].MemberEnd(); ++it)
270 m_filename[it->name.GetString()] = it->value.GetString();
274 for (
auto it = m_serializer.begin(); it != m_serializer.end(); ++it)
276 it->second->deserialize(m_netlist_load.get(), m_proj_dir);
281 bool ProjectManager::serialize_external(
bool shadow)
288 for (
auto it = m_serializer.begin(); it != m_serializer.end(); ++it)
293 m_filename[it->first] = relfile;
298 bool ProjectManager::serialize_to_projectfile(
bool shadow)
const
304 std::filesystem::create_directory(shadowPath);
305 projFilePath = shadowPath;
309 JsonWriteDocument doc;
314 if (!m_filename.empty())
316 JsonWriteObject& serial = doc.add_object(
"serializer");
317 for (
auto it = m_filename.begin(); it != m_filename.end(); ++it)
319 if (it->second.empty())
321 serial[it->first] = it->second;
325 return doc.serialize(projFilePath.string());
330 for (
auto it = m_filename.begin(); it != m_filename.end(); ++it)
332 std::cout <<
"serializer: <" << it->first <<
"> <" << it->second <<
">" << std::endl;
std::filesystem::path get_path() const
const GateLibrary * get_gate_library() const
std::filesystem::path get_filename(const std::string &relative_filename) const
std::filesystem::path get_relative_file_path(const std::string &filename) const
static const std::string s_shadow_dir
std::filesystem::path get_shadow_filename(const std::string &extension=std::string()) const
std::filesystem::path get_default_filename(const std::string &extension=std::string()) const
static ProjectManager * instance()
void set_project_status(ProjectStatus status)
bool create_project_directory(const std::string &path)
void unregister_serializer(const std::string &tagname)
bool serialize_project(Netlist *netlist, bool shadow=false)
std::unique_ptr< Netlist > & get_netlist()
void register_serializer(const std::string &tagname, ProjectSerializer *serializer)
void set_gate_library_path(const std::string &gl_path)
std::string get_filename(const std::string &serializer_name)
ProjectStatus get_project_status() const
void restore_project_file_from_autosave()
static const std::string s_project_file
std::string get_netlist_filename() const
bool open_project(const std::string &path="")
const ProjectDirectory & get_project_directory() const
bool remove_project_directory()
void set_project_directory(const std::string &path)
#define log_error(channel,...)
#define log_warning(channel,...)
std::unique_ptr< Netlist > load_netlist(const std::filesystem::path &netlist_file, const std::filesystem::path &gate_library_file=std::filesystem::path())
Create a netlist from the given file.
bool serialize_to_file(const Netlist *netlist, const std::filesystem::path &hal_file)
std::error_code error_code
const int SERIALIZATION_FORMAT_VERSION
This file contains various functions to create and load netlists.