Skip to content

Commit

Permalink
More encapsulated activities search API
Browse files Browse the repository at this point in the history
  • Loading branch information
khrykin committed Apr 24, 2020
1 parent 626f2e7 commit 7b4d88e
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 92 deletions.
102 changes: 76 additions & 26 deletions models/activitylist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,21 @@
// Created by Dmitry Khrykin on 2019-07-03.
//

#include "activitylist.h"
#include <iostream>
#include <algorithm>
#include <regex>
#include "utility.h"

#include <iostream>
#include <algorithm>
#include <regex>
#include "activitylist.h"
#include "utility.h"

void stg::activity_list::silently_add(const activity &activity) {
if (has(activity)) {
throw already_present_exception();
}

std::cout << "add_activity: " << activity << "\n";

_data.push_back(std::make_shared<stg::activity>(activity));

if (!search_query.empty())
search(search_query);
}

void stg::activity_list::add(const activity &activity) {
Expand All @@ -31,6 +27,9 @@ void stg::activity_list::add(const activity &activity) {

void stg::activity_list::silently_remove_at_index(stg::activity_index index) {
_data.erase(_data.begin() + index);

if (!search_query.empty())
search(search_query);
}

void stg::activity_list::remove_at_index(activity_index index) {
Expand All @@ -48,6 +47,10 @@ void stg::activity_list::silently_edit_at_index(activity_index index, const acti
}

_data[index] = std::make_shared<activity>(new_activity);

if (!search_query.empty()) {
search(search_query);
}
}

void stg::activity_list::edit_at_index(activity_index index, const activity &new_activity) {
Expand Down Expand Up @@ -98,17 +101,25 @@ std::string stg::activity_list::class_print_name() const {
stg::activity_list::activity_list(const std::vector<activity> &from_vector) {
std::transform(from_vector.begin(),
from_vector.end(),
std::back_inserter(_data), [](auto &activity) {
return std::make_shared<stg::activity>(activity);
});
std::back_inserter(_data),
[](auto &activity) {
return std::make_shared<stg::activity>(activity);
});

if (!search_query.empty())
search(search_query);
}

stg::activity_list::activity_list(const std::vector<std::shared_ptr<activity>> &from_vector) {
std::transform(from_vector.begin(),
from_vector.end(),
std::back_inserter(_data), [](auto &activity) {
return activity;
});
std::back_inserter(_data),
[](auto &activity) {
return activity;
});

if (!search_query.empty())
search(search_query);
}

const stg::activity &stg::activity_list::operator[](activity_index item_index) const {
Expand Down Expand Up @@ -145,29 +156,68 @@ stg::activity_list::index_of(const activity &activity) const {
return std::distance(_data.begin(), it);
}

stg::activity_list
stg::activity_list::search(std::string query) const {
query = std::regex_replace(query, std::regex("^\\s*"), "");
query = std::regex_replace(query, std::regex("\\s*$"), "");
bool stg::activity_list::search(std::string query) const {
text::strip_bounding_whitespaces(query);

search_query = query;

if (query.empty()) {
return activity_list{};
auto was_updated = !search_results.empty();
search_results.clear();

return was_updated;
}

query = text::utf8_fold_case(query);

std::vector<std::shared_ptr<activity>> results;
activity_list::data_t results;
std::copy_if(begin(),
end(),
std::back_inserter(results), [&query](auto activity) {
auto name = activity->name();
std::back_inserter(results),
[&query](auto activity) {
auto name = text::utf8_fold_case(activity->name());
return name.find(query) != std::string::npos;
});

auto was_updated = search_results != results;

search_results = results;

return was_updated;
}

const stg::activity_list::data_t &stg::activity_list::filtered() const {
if (search_query.empty())
return _data;

return search_results;
}

std::optional<stg::activity_list::index_t>
stg::activity_list::index_from_filtered(index_t index_in_filtered) const {
auto *activity = filtered().at(index_in_filtered).get();
return index_of(activity);
}

std::optional<stg::activity_list::index_t>
stg::activity_list::index_in_filtered(index_t activity_index) const {
auto activity = _data[activity_index];
auto it = std::find(filtered().begin(),
filtered().end(),
activity);

if (it == filtered().end())
return std::nullopt;

return std::distance(filtered().begin(), it);
}

name = text::utf8_fold_case(name);

return name.find(query) != std::string::npos;
});
void stg::activity_list::reset_with(data_t data) {
activity_list_base::reset_with(data);

return activity_list(results);
if (!search_query.empty())
search(search_query);
}

const char *stg::activity_list::already_present_exception::what() const noexcept {
Expand Down
10 changes: 9 additions & 1 deletion models/activitylist.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,20 @@ namespace stg {
std::optional<index_t> index_of(const activity *activity) const;
std::optional<index_t> index_of(const activity &activity) const;

activity_list search(std::string query) const;
bool search(std::string query) const;
const activity_list::data_t &filtered() const;
std::optional<index_t> index_from_filtered(index_t index_in_filtered) const;
std::optional<index_t> index_in_filtered(index_t activity_index) const;

void reset_with(data_t data) override;

std::string class_print_name() const override;
private:
friend strategy;

mutable std::string search_query;
mutable activity_list::data_t search_results;

void silently_add(const activity &activity) noexcept(false);
void add(const activity &activity) noexcept(false);

Expand Down
19 changes: 10 additions & 9 deletions models/currenttimemarker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
stg::current_time_marker::current_time_marker(const stg::strategy &strategy)
: strategy(strategy) {}

int stg::current_time_marker::top_offset_in(int total_height) const {
auto stg::current_time_marker::top_offset_in(int total_height) const -> int {
auto relative = relative_position();
if (relative < 0)
return 0;
Expand All @@ -17,20 +17,20 @@ int stg::current_time_marker::top_offset_in(int total_height) const {
return 1;
}

return static_cast<int>(total_height * relative_position());
return static_cast<int>(static_cast<float>(total_height) * relative_position());
}

bool stg::current_time_marker::is_visible() const {
auto stg::current_time_marker::is_visible() const -> bool {
auto relative = relative_position();
return relative >= 0 && relative <= 1;
}

bool stg::current_time_marker::is_hidden() const {
auto stg::current_time_marker::is_hidden() const -> bool {
return !is_visible();
}

stg::rect stg::current_time_marker::rect_in_parent(const rect &parent_rect,
int marker_radius) const {
auto stg::current_time_marker::rect_in_parent(const rect &parent_rect,
int marker_radius) const -> stg::rect {
return rect{
parent_rect.left - marker_radius,
parent_rect.top + top_offset_in(parent_rect.height) - marker_radius,
Expand All @@ -39,8 +39,8 @@ stg::rect stg::current_time_marker::rect_in_parent(const rect &parent_rect,
};
}

int stg::current_time_marker::scroll_offset_in_parent(const rect &parent_rect,
int window_height) const {
auto stg::current_time_marker::scroll_offset_in_parent(const rect &parent_rect,
int window_height) const -> int {
auto rect = rect_in_parent(parent_rect);
auto top_offset = rect.top - window_height / 2;

Expand All @@ -53,9 +53,10 @@ int stg::current_time_marker::scroll_offset_in_parent(const rect &parent_rect,
return top_offset;
}

float stg::current_time_marker::relative_position() const {
auto stg::current_time_marker::relative_position() const -> float {
auto strategy_duration_seconds = strategy.duration() * 60;
auto start_of_strategy_seconds = strategy.begin_time() * 60;

return static_cast<float>(stg::time_utils::current_seconds() - start_of_strategy_seconds)
/ strategy_duration_seconds;
}
16 changes: 8 additions & 8 deletions models/currenttimemarker.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ namespace stg {
public:
explicit current_time_marker(const strategy &strategy);

bool is_visible() const;
bool is_hidden() const;
auto is_visible() const -> bool;
auto is_hidden() const -> bool;

rect rect_in_parent(const rect &parent_rect,
int marker_radius = 0) const;
auto rect_in_parent(const rect &parent_rect,
int marker_radius = 0) const -> rect;

int scroll_offset_in_parent(const rect &parent_rect,
int window_height) const;
auto scroll_offset_in_parent(const rect &parent_rect,
int window_height) const -> int;
private:
const strategy &strategy;

int top_offset_in(int total_height) const;
float relative_position() const;
auto top_offset_in(int total_height) const -> int;
auto relative_position() const -> float;
};
}

Expand Down
2 changes: 2 additions & 0 deletions models/strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ const stg::activity_list &stg::strategy::activities() const {

void stg::strategy::silently_add_activity(const activity &activity) {
_activities.silently_add(activity);

commit_to_history();
}

void stg::strategy::add_activity(const activity &activity) {
_activities.add(activity);

commit_to_history();
}

Expand Down
6 changes: 3 additions & 3 deletions models/strategyhistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include "strategyhistory.h"

stg::strategy_history::strategy_history(entry current_state)
: current_state(std::move(current_state)) {}

bool stg::strategy_history::commit(const entry &new_state) {
if (new_state != current_state) {
undo_stack.push_back(current_state);
Expand Down Expand Up @@ -51,9 +54,6 @@ bool stg::strategy_history::has_next_state() {
return !redo_stack.empty();
}

stg::strategy_history::strategy_history(stg::strategy_history::entry current_state)
: current_state(std::move(current_state)) {}

bool stg::strategy_history::has_prevoius_activities_state() {
if (!has_prevoius_state())
return false;
Expand Down
15 changes: 4 additions & 11 deletions models/strategyhistory.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,10 @@ namespace stg {
time_slots_state::data_t time_slots;

friend bool operator==(const entry &lhs, const entry &rhs) {
auto &bigger_container = lhs.activities.size() >= rhs.activities.size()
? lhs.activities
: rhs.activities;

auto &smaller_container = lhs.activities.size() >= rhs.activities.size()
? rhs.activities
: lhs.activities;

auto activities_are_equal = std::equal(smaller_container.begin(),
smaller_container.end(),
bigger_container.begin(),
auto activities_are_equal = std::equal(lhs.activities.begin(),
lhs.activities.end(),
rhs.activities.begin(),
rhs.activities.end(),
[](const auto &l, const auto &r) {
return *l == *r;
});
Expand Down
6 changes: 6 additions & 0 deletions models/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define STRATEGR_UTILITY_H

#include <string>
#include <regex>
#include <codecvt>
#include <utf8proc.h>

Expand All @@ -24,5 +25,10 @@ namespace stg::text {
auto *lowered = (char *) utf8proc_NFKC_Casefold((utf8proc_uint8_t *) str.c_str());
return std::string(lowered);
}

inline void strip_bounding_whitespaces(std::string &str) {
str = std::regex_replace(str, std::regex("^\\s*"), "");
str = std::regex_replace(str, std::regex("\\s*$"), "");
}
}
#endif //STRATEGR_UTILITY_H
Loading

0 comments on commit 7b4d88e

Please sign in to comment.