Skip to content

Commit

Permalink
Script API: implement DateTime.CreateFromDate, CreateFromTime
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-mogilko committed Oct 11, 2024
1 parent b29002a commit 4dc0419
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Editor/AGS.Editor/Resources/agsdefns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2266,6 +2266,12 @@ builtin struct Maths {
builtin managed struct DateTime {
/// Gets the current date and time on the player's system.
readonly import static attribute DateTime* Now; // $AUTOCOMPLETESTATICONLY$
/// Creates DateTime object from the provided calendar and, optionally, time components
import static DateTime* CreateFromDate(int year, int month, int day, int hour = 0, int minute = 0, int second = 0); // $AUTOCOMPLETESTATICONLY$
/// Creates DateTime object from the provided time components
import static DateTime* CreateFromTime(int hour, int minute, int second); // $AUTOCOMPLETESTATICONLY$
/// Creates DateTime object from the provided raw time value (in seconds)
import static DateTime* CreateFromRawTime(int rawTime); // $AUTOCOMPLETESTATICONLY$
/// Gets the Year component of the date.
readonly import attribute int Year;
/// Gets the Month (1-12) component of the date.
Expand Down
47 changes: 46 additions & 1 deletion Engine/ac/datetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// https://opensource.org/license/artistic-2-0/
//
//=============================================================================
#include <time.h>
#include "ac/datetime.h"
#include "ac/dynobj/dynobj_manager.h"
#include "debug/debug_log.h"
#include "platform/base/agsplatformdriver.h"


Expand All @@ -23,6 +23,33 @@ ScriptDateTime* DateTime_Now() {
return sdt;
}

ScriptDateTime* DateTime_CreateFromDate(int year, int month, int day, int hour, int minute, int second) {
if (month < 1 || month > 12 || day < 1 || day > 31 || hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59)
{
debug_script_warn("DateTime.CreateFromDate: out of range date or time requested, result may be incorrect: %dy,%dm,%dd,%dh:%dm:%ds",
year, month, day, hour, minute, second);
}
ScriptDateTime *sdt = new ScriptDateTime(year, month, day, hour, minute, second);
ccRegisterManagedObject(sdt, sdt);
return sdt;
}

ScriptDateTime* DateTime_CreateFromTime(int hour, int minute, int second) {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59)
{
debug_script_warn("DateTime.CreateFromDate: out of range time requested, result may be incorrect: %dh:%dm:%ds",
hour, minute, second);
}
ScriptDateTime *sdt = new ScriptDateTime(0, 0, 0, hour, minute, second);
ccRegisterManagedObject(sdt, sdt);
return sdt;
}

ScriptDateTime* DateTime_CreateFromRawTime(int raw_time) {
ScriptDateTime *sdt = new ScriptDateTime(raw_time);
ccRegisterManagedObject(sdt, sdt);
return sdt;
}

int DateTime_GetYear(ScriptDateTime *sdt) {
return sdt->Year();
Expand Down Expand Up @@ -68,6 +95,21 @@ RuntimeScriptValue Sc_DateTime_Now(const RuntimeScriptValue *params, int32_t par
API_SCALL_OBJAUTO(ScriptDateTime, DateTime_Now);
}

RuntimeScriptValue Sc_DateTime_CreateFromRawTime(const RuntimeScriptValue *params, int32_t param_count)
{
API_SCALL_OBJAUTO_PINT(ScriptDateTime, DateTime_CreateFromRawTime);
}

RuntimeScriptValue Sc_DateTime_CreateFromDate(const RuntimeScriptValue *params, int32_t param_count)
{
API_SCALL_OBJAUTO_PINT6(ScriptDateTime, DateTime_CreateFromDate);
}

RuntimeScriptValue Sc_DateTime_CreateFromTime(const RuntimeScriptValue *params, int32_t param_count)
{
API_SCALL_OBJAUTO_PINT3(ScriptDateTime, DateTime_CreateFromTime);
}

// int (ScriptDateTime *sdt)
RuntimeScriptValue Sc_DateTime_GetYear(void *self, const RuntimeScriptValue *params, int32_t param_count)
{
Expand Down Expand Up @@ -114,6 +156,9 @@ void RegisterDateTimeAPI()
{
ScFnRegister datetime_api[] = {
{ "DateTime::get_Now", API_FN_PAIR(DateTime_Now) },
{ "DateTime::CreateFromDate", API_FN_PAIR(DateTime_CreateFromDate) },
{ "DateTime::CreateFromTime", API_FN_PAIR(DateTime_CreateFromTime) },
{ "DateTime::CreateFromRawTime", API_FN_PAIR(DateTime_CreateFromRawTime) },

{ "DateTime::get_DayOfMonth", API_FN_PAIR(DateTime_GetDayOfMonth) },
{ "DateTime::get_Hour", API_FN_PAIR(DateTime_GetHour) },
Expand Down
25 changes: 25 additions & 0 deletions Engine/ac/dynobj/scriptdatetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,28 @@ ScriptDateTime::ScriptDateTime(const ClockTimePoint &time)
SetTime(time);
}

ScriptDateTime::ScriptDateTime(int raw_time)
{
SetTime(ClockTimePoint(std::chrono::seconds(raw_time)));
}

ScriptDateTime::ScriptDateTime(int year, int month, int day, int hour, int minute, int second)
{
// NOTE: we do not init our calendar fields here directly, and instead
// go through SetTime, in case the combination of input values does not
// represent a true date, in which case it may be auto corrected when
// constructing a time point.
std::tm tm = { /* .tm_sec = */ second,
/* .tm_min = */ minute,
/* .tm_hour = */ hour,
/* .tm_mday = */ day,
/* .tm_mon = */ month - 1,
/* .tm_year = */ year - 1900,
};
tm.tm_isdst = -1; // use DST value from local time zone
SetTime(std::chrono::system_clock::from_time_t(std::mktime(&tm)));
}

void ScriptDateTime::SetTime(const ClockTimePoint &time)
{
// NOTE: subject to year 2038 problem due to shoving seconds since epoch into an int32
Expand All @@ -48,6 +70,9 @@ void ScriptDateTime::SetTime(const ClockTimePoint &time)

std::time_t ttime = SystemClock::to_time_t(time);
std::tm *newtime = std::localtime(&ttime);
if (newtime == nullptr)
return;

_hour = newtime->tm_hour;
_minute = newtime->tm_min;
_second = newtime->tm_sec;
Expand Down
4 changes: 4 additions & 0 deletions Engine/ac/dynobj/scriptdatetime.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ struct ScriptDateTime final : AGSCCDynamicObject
ScriptDateTime(const time_t &time);
// Constructs DateTime initialized using chrono::time_point
ScriptDateTime(const ClockTimePoint &time);
// Constructs DateTime initialized with raw time (unix time)
ScriptDateTime(int raw_time);
// Constructs DateTime initialized with all the date/time components
ScriptDateTime(int year, int month, int day, int hour, int minute, int second);

int Dispose(void *address, bool force) override;
const char *GetType() override;
Expand Down
5 changes: 5 additions & 0 deletions Engine/script/script_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,11 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f
RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \
return RuntimeScriptValue().SetScriptObject(ret_obj, ret_obj)

#define API_SCALL_OBJAUTO_PINT6(RET_CLASS, FUNCTION) \
ASSERT_PARAM_COUNT(FUNCTION, 6); \
RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \
return RuntimeScriptValue().SetScriptObject(ret_obj, ret_obj)

#define API_SCALL_OBJAUTO_PINT2_PBOOL(RET_CLASS, FUNCTION) \
ASSERT_PARAM_COUNT(FUNCTION, 3); \
RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].GetAsBool()); \
Expand Down

0 comments on commit 4dc0419

Please sign in to comment.