eris  1.4.0
A WorldForge client library.
Calendar.cpp
1 #ifdef HAVE_CONFIG_H
2  #include "config.h"
3 #endif
4 
5 #include "Calendar.h"
6 #include "Avatar.h"
7 #include "Exceptions.h"
8 #include "View.h"
9 #include "Entity.h"
10 #include "Log.h"
11 #include "iround.h"
12 
13 #include <cmath>
14 
15 #include <iostream>
16 
17 using namespace Atlas::Message;
18 
19 namespace Eris
20 {
21 
22 Calendar::Calendar(Avatar& av) :
23  m_avatar(av),
24  m_daysPerMonth(0),
25  m_monthsPerYear(0),
26  m_hoursPerDay(0),
27  m_minutesPerHour(0),
28  m_secondsPerMinute(0)
29 {
30  av.getView().TopLevelEntityChanged.connect(
31  sigc::mem_fun(this, &Calendar::topLevelEntityChanged));
32  // hook up right now if currently valid
33  if (av.getView().getTopLevel()) topLevelEntityChanged();
34 }
35 
36 void Calendar::topLevelEntityChanged()
37 {
38  m_calendarObserver.disconnect();
39  Entity* tl = m_avatar.getView().getTopLevel();
40  if (!tl || !tl->hasProperty("calendar")) return;
41 
42  m_calendarObserver = tl->observe("calendar", sigc::mem_fun(this, &Calendar::calendarAttrChanged), true);
43 }
44 
45 void Calendar::calendarAttrChanged(const Element& value)
46 {
47  //Reset the calendar first; if this is zero the dates will be invalid.
48  m_daysPerMonth = 0;
49 
50  if (value.isMap()) {
51  try {
52  initFromCalendarAttr(value.Map());
53  } catch (const InvalidAtlas& e) {
54  warning() << "Error when parsing calendar attribute. " << e.what();
55  }
56  }
57 }
58 
59 void Calendar::initFromCalendarAttr(const MapType& cal)
60 {
61  auto it = cal.find("days_per_month");
62  if (it == cal.end()) throw InvalidAtlas("malformed calendar data");
63  m_daysPerMonth = (int)it->second.asInt();
64 
65  it = cal.find("hours_per_day");
66  if (it == cal.end()) throw InvalidAtlas("malformed calendar data");
67  m_hoursPerDay = (int)it->second.asInt();
68 
69  it = cal.find("minutes_per_hour");
70  if (it == cal.end()) throw InvalidAtlas("malformed calendar data");
71  m_minutesPerHour = (int)it->second.asInt();
72 
73  it = cal.find("months_per_year");
74  if (it == cal.end()) throw InvalidAtlas("malformed calendar data");
75  m_monthsPerYear = (int)it->second.asInt();
76 
77  it = cal.find("seconds_per_minute");
78  if (it == cal.end()) throw InvalidAtlas("malformed calendar data");
79  m_secondsPerMinute = (int)it->second.asInt();
80 
81  Updated.emit();
82 }
83 
84 DateTime Calendar::now() const
85 {
86  DateTime n{};
87  // we don't have valid calendar data yet
88  if (m_daysPerMonth == 0) return n;
89 
90  long long world_time = L_ROUND(m_avatar.getWorldTime());
91 
92  n.m_seconds = world_time % m_secondsPerMinute;
93  world_time /= m_secondsPerMinute;
94 
95  n.m_minutes = world_time % m_minutesPerHour;
96  world_time /= m_minutesPerHour;
97 
98  n.m_hours = world_time % m_hoursPerDay;
99  world_time /= m_hoursPerDay;
100 
101  n.m_dayOfMonth = world_time % m_daysPerMonth;
102  world_time /= m_daysPerMonth;
103 
104  n.m_month = world_time % m_monthsPerYear;
105  world_time /= m_monthsPerYear;
106 
107  n.m_year = static_cast<int>(world_time);
108 
109  n.m_valid = true;
110  return n;
111 }
112 
113 } // of namespace Eris
Definition: Account.cpp:33