这是indexloc提供的服务,不要输入任何密码
Skip to content
1 change: 1 addition & 0 deletions libopenage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pxdgen(
add_subdirectory("audio")
add_subdirectory("console")
add_subdirectory("coord")
add_subdirectory("curve")
add_subdirectory("cvar")
add_subdirectory("datastructure")
add_subdirectory("gui")
Expand Down
2 changes: 2 additions & 0 deletions libopenage/coord/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ add_sources(libopenage
chunk.cpp
phys2.cpp
phys3.cpp
phys3_serialization.cpp
term.cpp
tests.cpp
tile.cpp
tile_serialization.cpp
tile3.cpp
vec2.cpp
vec2f.cpp
Expand Down
30 changes: 30 additions & 0 deletions libopenage/coord/phys3_serialization.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2016-2016 the openage authors. See copying.md for legal info.

#include "phys3_serialization.h"

namespace openage {
namespace coord {

std::ostream& operator<<(std::ostream &o, const phys3 &v) {
o << '(' << v.ne << ',' << v.se << ',' << v.up << ')';
return o;
}

std::ostream& operator<<(std::ostream &o, const phys3_delta &v) {
o << '(' << v.ne << ',' << v.se << ',' << v.up << ')';
return o;
}

std::istream& operator>>(std::istream &i, phys3 &v) {
char c;
i >> c >> v.ne >> c >> v.se >> c >> v.up >> c;
return i;
}

std::istream& operator>>(std::istream &i, phys3_delta &v) {
char c;
i >> c >> v.ne >> c >> v.se >> c >> v.up >> c;
return i;
}

}} // openage::coord
18 changes: 18 additions & 0 deletions libopenage/coord/phys3_serialization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2016-2016 the openage authors. See copying.md for legal info.

#pragma once

#include <iostream>

#include "phys3.h"

namespace openage {
namespace coord {

std::ostream& operator<<(std::ostream &o, const phys3 &v);
std::ostream& operator<<(std::ostream &o, const phys3_delta &v);

std::istream& operator>>(std::istream &i, phys3 &v);
std::istream& operator>>(std::istream &i, phys3_delta &v);

}} // openage::coord
30 changes: 30 additions & 0 deletions libopenage/coord/tile_serialization.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2016-2016 the openage authors. See copying.md for legal info.

#include "tile_serialization.h"

namespace openage {
namespace coord {

std::ostream& operator<<(std::ostream &o, const tile &v) {
o << '(' << v.ne << ',' << v.se << ')';
return o;
}

std::ostream& operator<<(std::ostream &o, const tile_delta &v) {
o << '(' << v.ne << ',' << v.se << ')';
return o;
}

std::istream& operator>>(std::istream &i, tile &v) {
char c;
i >> c >> v.ne >> c >> v.se >> c;
return i;
}

std::istream& operator>>(std::istream &i, tile_delta &v) {
char c;
i >> c >> v.ne >> c >> v.se >> c;
return i;
}

}} // openage::coord
18 changes: 18 additions & 0 deletions libopenage/coord/tile_serialization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2016-2016 the openage authors. See copying.md for legal info.

#pragma once

#include <iostream>

#include "tile.h"

namespace openage {
namespace coord {

std::ostream& operator<<(std::ostream &o, const tile &v);
std::ostream& operator<<(std::ostream &o, const tile_delta &v);

std::istream& operator>>(std::istream &i, tile &v);
std::istream& operator>>(std::istream &i, tile_delta &v);

}} // openage::coord
6 changes: 6 additions & 0 deletions libopenage/curve/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
add_sources(libopenage
curve_record_replay.cpp
entities_conductor.cpp
entities_conductor_interpolator.cpp
occurence_curve.cpp
)
75 changes: 75 additions & 0 deletions libopenage/curve/curve_record_replay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2016-2016 the openage authors. See copying.md for legal info.

#include "curve_record_replay.h"

#include <iostream>
#include <fstream>

#include "../unit/attribute_setter.h"

namespace openage {
namespace curve {

CurveRecordReplay::CurveRecordReplay(qtsdl::GuiItemLink *gui_link, bool recorder)
:
stream{std::make_unique<std::iostream>(recorder ? std::cerr.rdbuf() : std::cin.rdbuf())},
current_frame{},
recorder{recorder},
gui_link{gui_link} {
}

CurveRecordReplay::~CurveRecordReplay() {

}

std::string CurveRecordReplay::get_file_name() const {
return this->file_name;
}

void CurveRecordReplay::set_file_name(const std::string &file_name) {
if (this->file_name != file_name) {
this->stream = std::make_unique<std::fstream>(file_name, this->recorder ? std::ios_base::out : std::ios_base::in);
this->file_name = file_name;
}
}

CurveRecord::CurveRecord(qtsdl::GuiItemLink *gui_link)
:
CurveRecordReplay{gui_link, true} {
}

CurveRecord::~CurveRecord() {
}

void CurveRecord::perform(UnitContainer &placed_units) {
placed_units.update_all(*this);
++this->current_frame;
}

CurveReplay::CurveReplay(qtsdl::GuiItemLink *gui_link)
:
CurveRecordReplay{gui_link, false},
started{},
next_available_frame{} {
}

CurveReplay::~CurveReplay() {
}

void CurveReplay::perform(UnitContainer &placed_units) {
if (!this->started) {
*this->stream >> this->next_available_frame;
this->started = true;
}

while (this->next_available_frame <= this->current_frame) {
int id;
*this->stream >> id;
read_attr(*this->stream, id, placed_units);
*this->stream >> this->next_available_frame;
}

++this->current_frame;
}

}} // namespace openage::curve
78 changes: 78 additions & 0 deletions libopenage/curve/curve_record_replay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2016-2016 the openage authors. See copying.md for legal info.

#pragma once

#include <cstddef>
#include <string>
#include <iostream>
#include <memory>

namespace qtsdl {
class GuiItemLink;
} // qtsdl

namespace openage {

class UnitContainer;

namespace curve {

class CurveRecord;

class CurveRecordReplay {
public:
explicit CurveRecordReplay(qtsdl::GuiItemLink *gui_link, bool recorder);
virtual ~CurveRecordReplay();

std::string get_file_name() const;
void set_file_name(const std::string &file_name);

virtual void perform(UnitContainer &placed_units) = 0;

virtual CurveRecord* get_record() {
return nullptr;
}

protected:
std::string file_name;
std::unique_ptr<std::iostream> stream;
size_t current_frame;
const bool recorder;

public:
qtsdl::GuiItemLink *gui_link;
};

class CurveRecord : public CurveRecordReplay {
public:
explicit CurveRecord(qtsdl::GuiItemLink *gui_link);
virtual ~CurveRecord();

virtual void perform(UnitContainer &placed_units) override;

virtual CurveRecord* get_record() override {
return this;
}

template<typename T>
void write_out(id_t id, T value, const char *name) {
*this->stream << this->current_frame << " " << id << " " << name << " " << value << "\n";
this->stream->flush();
}

private:
};

class CurveReplay : public CurveRecordReplay {
public:
explicit CurveReplay(qtsdl::GuiItemLink *gui_link);
virtual ~CurveReplay();

virtual void perform(UnitContainer &placed_units) override;

private:
bool started;
size_t next_available_frame;
};

}} // namespace openage::curve
68 changes: 68 additions & 0 deletions libopenage/curve/entities_conductor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2015-2016 the openage authors. See copying.md for legal info.

#include "entities_conductor.h"

#include <algorithm>

#include "../error/error.h"

namespace openage {
namespace curve {

EntitiesConductor::EntitiesConductor(std::function<void(int, int, coord::phys2)> emerge, std::function<void(int)> vanish)
:
emerge{emerge},
vanish{vanish} {
}

void EntitiesConductor::jump(GameClock::moment from, GameClock::moment to) {
// TODO: call appear/vanish for every SPAWN/DIE (depending on the time direction)
// TODO: for each property find closest curve to 'to' that changes it, then apply the last value or a value that is sampled from curve at the 'to' moment
}

Prediction EntitiesConductor::predict_migration(GameClock::moment current_time, GameClock::moment other_time) const {
const auto prior = std::min(current_time, other_time);
const auto forth = std::max(current_time, other_time);

const auto cmp_start_cp = [](const OccurenceCurve &c, GameClock::moment p) { return c.origin.time < p; };
const auto cmp_start_pc = [](GameClock::moment p, const OccurenceCurve &c) { return p < c.origin.time; };

const auto cmp_end_ip = [this](size_t index, GameClock::moment p) { return end_time(this->history[index]) < p; };
const auto cmp_end_pi = [this](GameClock::moment p, size_t index) { return p < end_time(this->history[index]); };

ENSURE(this->history.size() == this->history_sorted_by_ends.size(), "index array out of sync");

const auto occurences_that_start_inside_begin_it = std::lower_bound(std::begin(this->history), std::end(this->history), prior, cmp_start_cp);
const auto occurences_that_start_inside_end_it = std::upper_bound(std::begin(this->history), std::end(this->history), forth, cmp_start_pc);

const auto occurencesthat_finish_inside_begin_it = std::lower_bound(std::begin(this->history_sorted_by_ends), std::end(this->history_sorted_by_ends), prior, cmp_end_ip);
const auto occurencesThat_finish_inside_end_it = std::upper_bound(std::begin(this->history_sorted_by_ends), std::end(this->history_sorted_by_ends), forth, cmp_end_pi);

decltype(this->history_sorted_by_ends) occurences_that_only_finish_inside;
const size_t completely_inside_begin_index = std::distance(std::begin(this->history), occurences_that_start_inside_begin_it);

std::copy_if(occurencesthat_finish_inside_begin_it, occurencesThat_finish_inside_end_it, std::back_inserter(occurences_that_only_finish_inside), [completely_inside_begin_index](size_t index) { return index < completely_inside_begin_index; });
std::sort(std::begin(occurences_that_only_finish_inside), std::end(occurences_that_only_finish_inside));

const auto occurences_that_start_inside_count = std::distance(occurences_that_start_inside_begin_it, occurences_that_start_inside_end_it);
std::vector<OccurenceCurve> trimmed(occurences_that_start_inside_count + occurences_that_only_finish_inside.size());

using namespace std::placeholders;
std::transform(occurences_that_start_inside_begin_it, occurences_that_start_inside_end_it, std::begin(trimmed), std::bind(&trim, _1, prior, forth));
std::transform(std::begin(occurences_that_only_finish_inside), std::end(occurences_that_only_finish_inside), std::begin(trimmed) + occurences_that_start_inside_count, [this, prior, forth](size_t index) {
return trim(this->history[index], prior, forth);
});

return trimmed;
}

void EntitiesConductor::converge(GameClock::moment current_time) {
// TODO: perform silently all rollbacks that unapplied_history causes (simplest: jump() back, fix history, jump() forward)
return;
}

void EntitiesConductor::append_history(const Prediction &unapplied_history) {
this->unapplied_history.insert(std::end(this->unapplied_history), std::begin(unapplied_history), std::end(unapplied_history));
}

}} // namespace openage::curve
Loading