Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split interfaces from universe continued #19

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions EndlessSkyLib.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
<Unit filename="source/DataFile.h" />
<Unit filename="source/DataNode.cpp" />
<Unit filename="source/DataNode.h" />
<Unit filename="source/DataObjectsLoader.cpp" />
<Unit filename="source/DataObjectsLoader.h" />
<Unit filename="source/DataWriter.cpp" />
<Unit filename="source/DataWriter.h" />
<Unit filename="source/Date.cpp" />
Expand Down Expand Up @@ -192,6 +194,8 @@
<Unit filename="source/Information.h" />
<Unit filename="source/Interface.cpp" />
<Unit filename="source/Interface.h" />
<Unit filename="source/InterfaceObjects.cpp" />
<Unit filename="source/InterfaceObjects.h" />
<Unit filename="source/ItemInfoDisplay.cpp" />
<Unit filename="source/ItemInfoDisplay.h" />
<Unit filename="source/JumpTypes.h" />
Expand Down
4 changes: 4 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ target_sources(EndlessSkyLib PRIVATE
DataFile.h
DataNode.cpp
DataNode.h
DataObjectsLoader.cpp
DataObjectsLoader.h
DataWriter.cpp
DataWriter.h
Date.cpp
Expand Down Expand Up @@ -178,6 +180,8 @@ target_sources(EndlessSkyLib PRIVATE
Information.h
Interface.cpp
Interface.h
InterfaceObjects.cpp
InterfaceObjects.h
ItemInfoDisplay.cpp
ItemInfoDisplay.h
JumpTypes.h
Expand Down
100 changes: 100 additions & 0 deletions source/DataObjectsLoader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* DataObjectsLoader.cpp
Copyright (c) 2022 by Michael Zahniser

Endless Sky is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.

Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "DataObjectsLoader.h"

#include "DataFile.h"
#include "DataNode.h"
#include "Files.h"
#include "Logger.h"

using namespace std;



DataObjectsLoader::DataObjectsLoader(UniverseObjects &universe, InterfaceObjects &interfaces)
: universe(universe), interfaces(interfaces)
{
}



future<void> DataObjectsLoader::Load(const vector<string> &sources, bool debugMode)
{
progress = 0.;

// We need to copy any variables used for loading to avoid a race condition.
// 'this' is not copied, so 'this' shouldn't be accessed after calling this
// function (except for calling GetProgress which is safe due to the atomic).
return async(launch::async, [this, sources, debugMode]() noexcept -> void
{
vector<string> files;
for(const string &source : sources)
{
// Iterate through the paths starting with the last directory given. That
// is, things in folders near the start of the path have the ability to
// override things in folders later in the path.
auto list = Files::RecursiveList(source + "data/");
files.reserve(files.size() + list.size());
files.insert(files.end(),
make_move_iterator(list.begin()),
make_move_iterator(list.end()));
}

const double step = 1. / (static_cast<int>(files.size()) + 1);
for(const auto &path : files)
{
LoadFile(path, debugMode);

// Increment the atomic progress by one step.
// We use acquire + release to prevent any reordering.
auto val = progress.load(memory_order_acquire);
progress.store(val + step, memory_order_release);
}
FinishLoading();
progress = 1.;
});
}



double DataObjectsLoader::GetProgress() const
{
return progress.load(memory_order_acquire);
}



void DataObjectsLoader::FinishLoading()
{
universe.FinishLoading();
}



void DataObjectsLoader::LoadFile(const string &path, bool debugMode)
{
// This is an ordinary file. Check to see if it is an image.
if(path.length() < 4 || path.compare(path.length() - 4, 4, ".txt"))
return;

DataFile data(path);
if(debugMode)
Logger::LogError("Parsing: " + path);

for(const DataNode &node : data)
if(!(universe.LoadNode(node, path) || interfaces.LoadNode(node)))
node.PrintTrace("Skipping unrecognized root object:");
}
56 changes: 56 additions & 0 deletions source/DataObjectsLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* DataObjectsLoader.h
Copyright (c) 2022 by Michael Zahniser

Endless Sky is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.

Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef DATA_OBJECTS_LOADER_H_
#define DATA_OBJECTS_LOADER_H_

#include "InterfaceObjects.h"
#include "UniverseObjects.h"

#include <future>



// This class contains the loader for serialized game data. The serialized
// game data contains various types of intermixed data (interfaces, outfits,
// ships, missions) so the loader does need to load to different Object stores.
class DataObjectsLoader {
public:
DataObjectsLoader(UniverseObjects &universe, InterfaceObjects &interfaces);

// Load game objects from the given directories of definitions.
std::future<void> Load(const std::vector<std::string> &sources, bool debugMode = false);
// Determine the fraction of data files read from disk.
double GetProgress() const;
// Resolve every game object dependency.
void FinishLoading();


private:
void LoadFile(const std::string &path, bool debugMode = false);


private:
// A value in [0, 1] representing how many source files have been processed for content.
std::atomic<double> progress;


private:
// References to the objects we are loading into;
UniverseObjects &universe;
InterfaceObjects &interfaces;
};

#endif
32 changes: 14 additions & 18 deletions source/GameData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include "Conversation.h"
#include "DataFile.h"
#include "DataNode.h"
#include "DataObjectsLoader.h"
#include "DataWriter.h"
#include "Effect.h"
#include "Files.h"
Expand All @@ -37,6 +38,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include "Hazard.h"
#include "ImageSet.h"
#include "Interface.h"
#include "InterfaceObjects.h"
#include "LineShader.h"
#include "MaskManager.h"
#include "Minable.h"
Expand Down Expand Up @@ -74,6 +76,9 @@ using namespace std;

namespace {
UniverseObjects objects;
InterfaceObjects interfaces;
DataObjectsLoader dataLoader(objects, interfaces);

Set<Fleet> defaultFleets;
Set<Government> defaultGovernments;
Set<Planet> defaultPlanets;
Expand Down Expand Up @@ -163,7 +168,7 @@ future<void> GameData::BeginLoad(bool onlyLoadData, bool debugMode)
Music::Init(sources);
}

return objects.Load(sources, debugMode);
return dataLoader.Load(sources, debugMode);
}


Expand All @@ -190,6 +195,7 @@ void GameData::FinishLoading()
void GameData::CheckReferences()
{
objects.CheckReferences();
interfaces.CheckReferences();
}


Expand Down Expand Up @@ -225,7 +231,7 @@ double GameData::GetProgress()
if(initiallyLoaded)
return 1.;

double val = min(min(spriteQueue.GetProgress(), Audio::GetProgress()), objects.GetProgress());
double val = min(min(spriteQueue.GetProgress(), Audio::GetProgress()), dataLoader.GetProgress());
if(val >= 1.)
initiallyLoaded = true;
return val;
Expand Down Expand Up @@ -518,7 +524,7 @@ void GameData::DestroyPersons(vector<string> &names)

const Set<Color> &GameData::Colors()
{
return objects.colors;
return interfaces.Colors();
}


Expand Down Expand Up @@ -582,7 +588,7 @@ const Set<Hazard> &GameData::Hazards()

const Set<Interface> &GameData::Interfaces()
{
return objects.interfaces;
return interfaces.Interfaces();
}


Expand Down Expand Up @@ -801,31 +807,21 @@ void GameData::SetHaze(const Sprite *sprite, bool allowAnimation)

const string &GameData::Tooltip(const string &label)
{
static const string EMPTY;
auto it = objects.tooltips.find(label);
// Special case: the "cost" and "sells for" labels include the percentage of
// the full price, so they will not match exactly.
if(it == objects.tooltips.end() && !label.compare(0, 4, "cost"))
it = objects.tooltips.find("cost:");
if(it == objects.tooltips.end() && !label.compare(0, 9, "sells for"))
it = objects.tooltips.find("sells for:");
return (it == objects.tooltips.end() ? EMPTY : it->second);
return interfaces.Tooltip(label);
}



string GameData::HelpMessage(const string &name)
{
static const string EMPTY;
auto it = objects.helpMessages.find(name);
return Command::ReplaceNamesWithKeys(it == objects.helpMessages.end() ? EMPTY : it->second);
return interfaces.HelpMessage(name);
}



const map<string, string> &GameData::HelpTemplates()
{
return objects.helpMessages;
return interfaces.HelpTemplates();
}


Expand Down Expand Up @@ -899,5 +895,5 @@ map<string, shared_ptr<ImageSet>> GameData::FindImages()
// Thread-safe way to draw the menu background.
void GameData::DrawMenuBackground(Panel *panel)
{
objects.DrawMenuBackground(panel);
interfaces.DrawMenuBackground(panel);
}
Loading