Skip to content

Commit

Permalink
improve calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
AMOSOMNUM committed Dec 6, 2023
1 parent 65f46c9 commit 71b6bac
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 102 deletions.
29 changes: 1 addition & 28 deletions src/controller/evento_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@
#include "undertaking_evento_model.h"
#include "user_helper.h"

#include <QDateTime>

#include <algorithm>
#include <array>
#include <set>
#include <vector>

void EventoService::load_Plaza() {
std::array<QFuture<bool>, 2> tasks = {
Expand Down Expand Up @@ -462,27 +457,5 @@ EventoBrief::EventoBrief(const DTO_Evento& src)
EventoBlock::EventoBlock(const DTO_Evento& src, const std::set<EventoID>& permitted)
: id(src.id), title(src.title), gmtEventStart(src.gmtEventStart), gmtEventEnd(src.gmtEventEnd),
editable(permitted.count(src.id)) {
if (gmtEventStart.date() == gmtEventEnd.date()) {
auto time = gmtEventStart.time();
if (time.hour() < 8)
start.ahead = 1;
else
start.major = (time.hour() - 8);
if (time.hour() != 23)
start.fraction = (time.minute() * 60 + time.second()) / 450;
time = gmtEventEnd.time();
if (time.hour() >= 8)
end.major = (time.hour() - 8);
if (time.hour() == 23 && time != QTime(23, 0))
end.ahead = 1;
else
end.fraction = (time.minute() * 60 + time.second()) / 450;
column_or_flag = gmtEventStart.date().dayOfWeek() - 1;
} else {
if (getMonday(gmtEventStart.date()) == getMonday(gmtEventEnd.date())) {
column_or_flag = -1;
start.major = gmtEventStart.date().dayOfWeek() - 1;
end.major = gmtEventEnd.date().dayOfWeek();
}
}
init();
}
91 changes: 62 additions & 29 deletions src/domain/entity/evento_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,45 @@

struct DTO_Evento;

struct TimePoint {
uint8_t fraction : 3;
uint8_t major : 4;
uint8_t ahead : 1;
struct IEEE_Float {
uint32_t m : 23;
uint32_t e : 8;
uint32_t sign : 1;

operator uint8_t() {
return *reinterpret_cast<uint8_t*>(this);
operator float() {
return *reinterpret_cast<float*>(this);
}
};

TimePoint() {
*(uint8_t*)this = 0;
template <int major_bits = 4>
struct FixedPoint {
uint8_t fraction : 7 - major_bits;
uint8_t major : major_bits;
uint8_t out_of_range : 1;

operator uint8_t() const {
return *reinterpret_cast<const uint8_t*>(this);
}

struct IEEE_Float {
uint32_t m : 23;
uint32_t e : 8;
uint32_t sign : 1;
template <int other>
operator FixedPoint<other>() const {
return *reinterpret_cast<std::enable_if_t<other != major_bits, const FixedPoint<other>>*>(
this);
}

operator float() {
return *reinterpret_cast<float*>(this);
}
};
FixedPoint() {
*(uint8_t*)this = 0;
}

static inline float to_float(TimePoint t) {
static inline float to_float(FixedPoint t) {
constexpr uint32_t M_OPRAND = 0b100'00000'00000'00000'00000;
static_assert(QSysInfo::ByteOrder == QSysInfo::LittleEndian, "Big Endian Untested!");
if (t.ahead)
if (t.out_of_range)
return t.major ? t.major + 0.5 : -0.5;
if (!t.major && !t.fraction)
return 0;
t.ahead = 0;
IEEE_Float result;
result.e = 127 + 20; // 24 - bitsize of (major)
result.e = 127 + 24 - major_bits; // 24 - bitsize of (major)
result.m = t;
result.sign = 0;
while (!(result.m & M_OPRAND)) {
Expand All @@ -52,14 +58,19 @@ struct TimePoint {
}
};

inline QDate getMonday(QDate date) {
auto day_of_week = date.dayOfWeek() - 1;
return date.addDays(-day_of_week);
}

struct EventoBlock {
EventoID id = -1;
QString title;
QDateTime gmtEventStart;
QDateTime gmtEventEnd;
int8_t column_or_flag = -2;
TimePoint start; // index: 8:00 -> 0
TimePoint end; // index: 23:00 -> 15
FixedPoint<> start;
FixedPoint<> end;
bool editable = false;
int depth = -1;

Expand All @@ -70,20 +81,42 @@ struct EventoBlock {
if (column_or_flag >= -1)
return;
if (gmtEventStart.date() < monday)
start.ahead = 1;
start.out_of_range = 1;
else
start.major = gmtEventStart.date().dayOfWeek() - 1;
if (gmtEventEnd.date() > monday.addDays(6)) {
end.ahead = 1;
end.out_of_range = 1;
end.major = 7;
} else
end.major = gmtEventEnd.date().dayOfWeek();
}
};

static inline QDate getMonday(QDate date) {
auto day_of_week = date.dayOfWeek() - 1;
return date.addDays(-day_of_week);
}
private:
void init() {
if (gmtEventStart.date() == gmtEventEnd.date()) {
auto time = gmtEventStart.time();
if (time.hour() < 8)
start.out_of_range = 1;
else
start.major = time.hour() - 8;
if (time.hour() != 23)
start.fraction = (time.minute() * 60 + time.second()) / 450;
time = gmtEventEnd.time();
if (time.hour() > 8)
end.major = time.hour() - 8;
if (time.hour() == 23 && time != QTime(23, 0))
end.out_of_range = 1;
if (time.hour() >= 8)
end.fraction = (time.minute() * 60 + time.second()) / 450;
column_or_flag = gmtEventStart.date().dayOfWeek() - 1;
} else {
if (getMonday(gmtEventStart.date()) == getMonday(gmtEventEnd.date())) {
column_or_flag = -1;
start.major = gmtEventStart.date().dayOfWeek() - 1;
end.major = gmtEventEnd.date().dayOfWeek();
}
}
}
};

#endif // EVENTOBLOCK_H
69 changes: 43 additions & 26 deletions src/domain/model/evento_block_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,19 @@ QVariant EventoBlockModel::data(const QModelIndex& index, int role) const {
case Role::Column:
return element.column_or_flag;
case Role::Start:
return TimePoint::to_float(element.start);
return FixedPoint<>::to_float(element.start);
case Role::End:
return TimePoint::to_float(element.end);
return FixedPoint<>::to_float(element.end);
case Role::Editable:
return element.editable;
case Role::Depth:
return element.depth;
case Role::DepthMax:
return element.column_or_flag < 0 ? all_day_line_max
: z_map[element.column_or_flag][element.start.major];
if (element.column_or_flag < 0)
return all_day_line_max;
if (element.start.out_of_range)
return z_map[element.column_or_flag][31];
return z_map[element.column_or_flag][static_cast<FixedPoint<5>>(element.start).major];
}

return QVariant();
Expand Down Expand Up @@ -89,18 +92,20 @@ void EventoBlockModel::arrange_pipeline(QDate monday) {
std::vector<int> all_day;
std::vector<ALL_DAY_MAP_FLAG> all_day_map;
std::array<std::vector<Z_MAP_FLAG>, 7> z_map_layout = {};
std::array<std::array<Z_MAP_FLAG, 15>, 7> z_map_rel = {};
auto max = m_data.size();
std::array<std::array<Z_MAP_FLAG, 32>, 7> z_map_rel = {};

z_map = {};
for (auto& i : z_map_layout)
i.push_back(INIT);
bucket.emplace_back();

// Generate Depth Infos
auto max = m_data.size();
for (auto i = 0; i < max; ++i) {
auto& element = m_data[i];
element.fresh(monday);
if (element.column_or_flag < 0) {
// Multi-day
ALL_DAY_MAP_FLAG flag = NUL;
for (auto index = element.start.major; index <= element.end.major; ++index)
flag = ALL_DAY_MAP_FLAG(flag | all_day_dict[index]);
Expand All @@ -118,20 +123,28 @@ void EventoBlockModel::arrange_pipeline(QDate monday) {
}
all_day.push_back(i);
} else {
auto end = element.end.major;
if (!end) {
element.depth = 0;
continue;
}
if (!element.end.fraction)
end--;
// Normal
auto column = element.column_or_flag;
auto start = static_cast<FixedPoint<5>>(element.start);
auto end = static_cast<FixedPoint<5>>(element.end);
auto end_max = end.major;
if (end_max && !end.fraction)
end_max--;
Z_MAP_FLAG flag = INIT;
for (auto index = element.start.major; index <= end; ++index)
for (auto index = start.major; index <= end_max; ++index)
flag = Z_MAP_FLAG(flag | dict[index]);
auto& rel = z_map_rel[element.column_or_flag];
for (auto index = element.start.major; index <= end; ++index)
if (end.out_of_range)
flag = Z_MAP_FLAG(flag | After_PM_11);
if (start.out_of_range)
flag = Z_MAP_FLAG(flag | Before_AM_8);
auto& rel = z_map_rel[column];
for (auto index = start.major; index <= end_max; ++index)
rel[index] = Z_MAP_FLAG(rel[index] | flag);
auto& layout = z_map_layout[element.column_or_flag];
if (end.out_of_range)
rel[30] = Z_MAP_FLAG(rel[30] | flag);
if (start.out_of_range)
rel[31] = Z_MAP_FLAG(rel[31] | flag);
auto& layout = z_map_layout[column];
auto max = layout.size();
std::size_t j;
for (j = 0; j < max; j++)
Expand All @@ -145,10 +158,14 @@ void EventoBlockModel::arrange_pipeline(QDate monday) {
element.depth = max;
bucket.emplace_back();
}
auto& col = z_map[element.column_or_flag];
for (auto index = element.start.major; index <= end; ++index)
auto& col = z_map[column];
for (auto index = start.major; index <= end_max; ++index)
if (col[index] < element.depth)
col[index] = element.depth;
if (end.out_of_range)
col[30] = element.depth;
if (start.out_of_range)
col[31] = element.depth;
bucket[element.depth].push_back(i);
}
}
Expand All @@ -162,21 +179,21 @@ void EventoBlockModel::arrange_pipeline(QDate monday) {
this->setProperty("all_day_line_num", (quint64)all_day_map.size());
// update z_map
for (auto col = 0; col < 7; col++) {
auto& map = z_map[col];
Z_MAP_FLAG processed = INIT;
Z_MAP_FLAG current_set;
int max;
for (auto i = 0; i < 15; i++)
for (auto i = 0; i < 32; i++)
if (!(processed & dict[i])) {
current_set = dict[i];
max = z_map[col][i];
max = map[i];
auto rel = z_map_rel[col][i];
auto will_visit = Z_MAP_FLAG(rel & (rel ^ current_set));
if (!will_visit) {
processed = Z_MAP_FLAG(processed | current_set);
continue;
}
int count = 14;
auto& map = z_map[col];
int count = 31;
while (will_visit) {
if (will_visit & dict[count]) {
if (max < map[count])
Expand All @@ -186,12 +203,12 @@ void EventoBlockModel::arrange_pipeline(QDate monday) {
will_visit = Z_MAP_FLAG(rel & (rel ^ current_set));
}
if (!count)
count = 14;
count = 31;
else
count--;
}
for (count = 0; count < 15; count++)
if (processed & dict[count])
for (count = 0; count < 32; count++)
if (current_set & dict[count])
map[count] = max;
processed = Z_MAP_FLAG(processed | current_set);
}
Expand Down
57 changes: 38 additions & 19 deletions src/domain/model/evento_block_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class EventoBlockModel : public QAbstractListModel {

std::vector<EventoBlock> m_data;
std::vector<int> pipeline;
std::array<std::array<int, 16>, 7> z_map = {};
std::array<std::array<int, 32>, 7> z_map = {};
int all_day_line_max;

enum ALL_DAY_MAP_FLAG : uint8_t {
Expand All @@ -58,27 +58,46 @@ class EventoBlockModel : public QAbstractListModel {
};
static constexpr const ALL_DAY_MAP_FLAG all_day_dict[] = {MON, TUE, WED, THU, FRI, SAT, SUN};

enum Z_MAP_FLAG : uint16_t {
AM_8 = 1 << 0,
AM_9 = 1 << 1,
AM_10 = 1 << 2,
AM_11 = 1 << 3,
AM_12 = 1 << 4,
PM_1 = 1 << 5,
PM_2 = 1 << 6,
PM_3 = 1 << 7,
PM_4 = 1 << 8,
PM_5 = 1 << 9,
PM_6 = 1 << 10,
PM_7 = 1 << 11,
PM_8 = 1 << 12,
PM_9 = 1 << 13,
PM_10 = 1 << 14,
enum Z_MAP_FLAG : uint32_t {
AM_8 = 1u << 0,
AM_8_30 = 1u << 1,
AM_9 = 1u << 2,
AM_9_30 = 1u << 3,
AM_10 = 1u << 4,
AM_10_30 = 1u << 5,
AM_11 = 1u << 6,
AM_11_30 = 1u << 7,
AM_12 = 1u << 8,
AM_12_30 = 1u << 9,
PM_1 = 1u << 10,
PM_1_30 = 1u << 11,
PM_2 = 1u << 12,
PM_2_30 = 1u << 13,
PM_3 = 1u << 14,
PM_3_30 = 1u << 15,
PM_4 = 1u << 16,
PM_4_30 = 1u << 17,
PM_5 = 1u << 18,
PM_5_30 = 1u << 19,
PM_6 = 1u << 20,
PM_6_30 = 1u << 21,
PM_7 = 1u << 22,
PM_7_30 = 1u << 23,
PM_8 = 1u << 24,
PM_8_30 = 1u << 25,
PM_9 = 1u << 26,
PM_9_30 = 1u << 27,
PM_10 = 1u << 28,
PM_10_30 = 1u << 29,
After_PM_11 = 1u << 30,
Before_AM_8 = 1u << 31,
INIT = 0
};
static constexpr const Z_MAP_FLAG dict[] = {
AM_8, AM_9, AM_10, AM_11, AM_12, PM_1, PM_2, PM_3,
PM_4, PM_5, PM_6, PM_7, PM_8, PM_9, PM_10,
AM_8, AM_8_30, AM_9, AM_9_30, AM_10, AM_10_30, AM_11, AM_11_30,
AM_12, AM_12_30, PM_1, PM_1_30, PM_2, PM_2_30, PM_3, PM_3_30,
PM_4, PM_4_30, PM_5, PM_5_30, PM_6, PM_6_30, PM_7, PM_7_30,
PM_8, PM_8_30, PM_9, PM_9_30, PM_10, PM_10_30, After_PM_11, Before_AM_8,
};

private:
Expand Down

0 comments on commit 71b6bac

Please sign in to comment.