Line data Source code
1 0 : /*
2 :
3 : OOJSClock.m
4 :
5 :
6 : Oolite
7 : Copyright (C) 2004-2013 Giles C Williams and contributors
8 :
9 : This program is free software; you can redistribute it and/or
10 : modify it under the terms of the GNU General Public License
11 : as published by the Free Software Foundation; either version 2
12 : of the License, or (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 : MA 02110-1301, USA.
23 :
24 : */
25 :
26 : #import "OOJSClock.h"
27 : #import "OOJavaScriptEngine.h"
28 : #import "Universe.h"
29 : #import "OOJSPlayer.h"
30 : #import "PlayerEntity.h"
31 : #import "PlayerEntityScriptMethods.h"
32 : #import "OOStringParsing.h"
33 : #import "OODebugStandards.h"
34 :
35 : static JSBool ClockGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
36 :
37 : // Methods
38 : static JSBool JSClockToString(JSContext *context, uintN argc, jsval *vp);
39 : static JSBool ClockClockStringForTime(JSContext *context, uintN argc, jsval *vp);
40 : static JSBool ClockAddSeconds(JSContext *context, uintN argc, jsval *vp);
41 :
42 :
43 0 : static JSClass sClockClass =
44 : {
45 : "Clock",
46 : JSCLASS_HAS_PRIVATE,
47 :
48 : JS_PropertyStub, // addProperty
49 : JS_PropertyStub, // delProperty
50 : ClockGetProperty, // getProperty
51 : JS_StrictPropertyStub, // setProperty
52 : JS_EnumerateStub, // enumerate
53 : JS_ResolveStub, // resolve
54 : JS_ConvertStub, // convert
55 : JS_FinalizeStub, // finalize
56 : JSCLASS_NO_OPTIONAL_MEMBERS
57 : };
58 :
59 :
60 0 : enum
61 : {
62 : // Property IDs
63 : kClock_absoluteSeconds, // game real time clock, double, read-only
64 : kClock_seconds, // game clock time, double, read-only
65 : kClock_minutes, // game clock time minutes (rounded down), integer double, read-only
66 : kClock_hours, // game clock time hours (rounded down), integer double, read-only
67 : kClock_days, // game clock time days (rounded down), int, read-only
68 : kClock_secondsComponent, // second component of game clock time, double, read-only
69 : kClock_minutesComponent, // minute component of game clock time (rounded down), int, read-only
70 : kClock_hoursComponent, // hour component of game clock time (rounded down), int, read-only
71 : kClock_daysComponent, // day component of game clock time (rounded down), int, read-only
72 : kClock_clockString, // game clock time as display string, string, read-only
73 : kClock_isAdjusting, // clock is adjusting, boolean, read-only
74 : kClock_adjustedSeconds, // game clock time, including adjustments, double, read-only
75 : kClock_legacy_scriptTimer // legacy scriptTimer_number, double, read-only
76 : };
77 :
78 :
79 0 : static JSPropertySpec sClockProperties[] =
80 : {
81 : // JS name ID flags
82 : { "absoluteSeconds", kClock_absoluteSeconds, OOJS_PROP_READONLY_CB },
83 : { "seconds", kClock_seconds, OOJS_PROP_READONLY_CB },
84 : { "minutes", kClock_minutes, OOJS_PROP_READONLY_CB },
85 : { "hours", kClock_hours, OOJS_PROP_READONLY_CB },
86 : { "days", kClock_days, OOJS_PROP_READONLY_CB },
87 : { "secondsComponent", kClock_secondsComponent, OOJS_PROP_READONLY_CB },
88 : { "minutesComponent", kClock_minutesComponent, OOJS_PROP_READONLY_CB },
89 : { "hoursComponent", kClock_hoursComponent, OOJS_PROP_READONLY_CB },
90 : { "daysComponent", kClock_daysComponent, OOJS_PROP_READONLY_CB },
91 : { "clockString", kClock_clockString, OOJS_PROP_READONLY_CB },
92 : { "isAdjusting", kClock_isAdjusting, OOJS_PROP_READONLY_CB },
93 : { "adjustedSeconds", kClock_adjustedSeconds, OOJS_PROP_READONLY_CB },
94 : { "legacy_scriptTimer", kClock_legacy_scriptTimer, OOJS_PROP_READONLY_CB },
95 : { 0 }
96 : };
97 :
98 :
99 0 : static JSFunctionSpec sClockMethods[] =
100 : {
101 : // JS name Function min args
102 : { "toString", JSClockToString, 0 },
103 : { "clockStringForTime", ClockClockStringForTime, 1 },
104 : { "addSeconds", ClockAddSeconds, 1 },
105 : { 0 }
106 : };
107 :
108 :
109 0 : void InitOOJSClock(JSContext *context, JSObject *global)
110 : {
111 : JSObject *clockPrototype = JS_InitClass(context, global, NULL, &sClockClass, OOJSUnconstructableConstruct, 0, sClockProperties, sClockMethods, NULL, NULL);
112 : JS_DefineObject(context, global, "clock", &sClockClass, clockPrototype, OOJS_PROP_READONLY);
113 : }
114 :
115 :
116 0 : static JSBool ClockGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
117 : {
118 : if (!JSID_IS_INT(propID)) return YES;
119 :
120 : OOJS_NATIVE_ENTER(context)
121 :
122 : PlayerEntity *player = OOPlayerForScripting();
123 : double clockTime;
124 :
125 : clockTime = [player clockTime];
126 :
127 : switch (JSID_TO_INT(propID))
128 : {
129 : case kClock_absoluteSeconds:
130 : return JS_NewNumberValue(context, [UNIVERSE getTime], value);
131 :
132 : case kClock_seconds:
133 : return JS_NewNumberValue(context, clockTime, value);
134 :
135 : case kClock_minutes:
136 : return JS_NewNumberValue(context, floor(clockTime / 60.0), value);
137 :
138 : case kClock_hours:
139 : return JS_NewNumberValue(context, floor(clockTime /3600.0), value);
140 : return YES;
141 :
142 : case kClock_secondsComponent:
143 : *value = INT_TO_JSVAL(fmod(clockTime, 60.0));
144 : return YES;
145 :
146 : case kClock_minutesComponent:
147 : *value = INT_TO_JSVAL(fmod(floor(clockTime / 60.0), 60.0));
148 : return YES;
149 :
150 : case kClock_hoursComponent:
151 : *value = INT_TO_JSVAL(fmod(floor(clockTime / 3600.0), 24.0));
152 : return YES;
153 :
154 : case kClock_days:
155 : case kClock_daysComponent:
156 : *value = INT_TO_JSVAL(floor(clockTime / 86400.0));
157 : return YES;
158 :
159 : case kClock_clockString:
160 : *value = OOJSValueFromNativeObject(context, [player dial_clock]);
161 : return YES;
162 :
163 : case kClock_isAdjusting:
164 : *value = OOJSValueFromBOOL([player clockAdjusting]);
165 : return YES;
166 :
167 : case kClock_adjustedSeconds:
168 : return JS_NewNumberValue(context, [player clockTimeAdjusted], value);
169 :
170 : case kClock_legacy_scriptTimer:
171 : OOStandardsDeprecated(@"The legacy_scriptTimer property is deprecated");
172 : return JS_NewNumberValue(context, [player scriptTimer], value);
173 :
174 : default:
175 : OOJSReportBadPropertySelector(context, this, propID, sClockProperties);
176 : return NO;
177 : }
178 :
179 : OOJS_NATIVE_EXIT
180 : }
181 :
182 :
183 : // *** Methods ***
184 :
185 : // toString() : String
186 0 : static JSBool JSClockToString(JSContext *context, uintN argc, jsval *vp)
187 : {
188 : OOJS_NATIVE_ENTER(context)
189 :
190 : OOJS_RETURN_OBJECT([OOPlayerForScripting() dial_clock]);
191 :
192 : OOJS_NATIVE_EXIT
193 : }
194 :
195 :
196 : // clockStringForTime(time : Number) : String
197 0 : static JSBool ClockClockStringForTime(JSContext *context, uintN argc, jsval *vp)
198 : {
199 : OOJS_NATIVE_ENTER(context)
200 :
201 : double time;
202 :
203 : if (EXPECT_NOT(argc < 1 || !JS_ValueToNumber(context, OOJS_ARGV[0], &time)))
204 : {
205 : jsval arg = JSVAL_VOID;
206 : if (argc > 0) arg = OOJS_ARGV[0];
207 : OOJSReportBadArguments(context, @"Clock", @"clockStringForTime", 1, &arg, nil, @"number");
208 : return NO;
209 : }
210 :
211 : OOJS_RETURN_OBJECT(ClockToString(time, NO));
212 :
213 : OOJS_NATIVE_EXIT
214 : }
215 :
216 :
217 : // addSeconds(seconds : Number) : String
218 0 : static JSBool ClockAddSeconds(JSContext *context, uintN argc, jsval *vp)
219 : {
220 : OOJS_NATIVE_ENTER(context)
221 :
222 : double time;
223 : const double kMaxTime = 30.0 * 24.0 * 3600.0; // 30 days
224 :
225 : if (EXPECT_NOT(argc < 1 || !JS_ValueToNumber(context, OOJS_ARGV[0], &time)))
226 : {
227 : jsval arg = JSVAL_VOID;
228 : if (argc > 0) arg = OOJS_ARGV[0];
229 : OOJSReportBadArguments(context, @"Clock", @"addSeconds", 1, &arg, nil, @"number");
230 : return NO;
231 : }
232 :
233 : if (time > kMaxTime || time < 1.0 || !isfinite(time))
234 : {
235 : OOJS_RETURN_BOOL(NO);
236 : }
237 :
238 : [OOPlayerForScripting() addToAdjustTime:time];
239 :
240 : OOJS_RETURN_BOOL(YES);
241 :
242 : OOJS_NATIVE_EXIT
243 : }
|