Whoa -- actually the current Java API for dates and times is seriously broken. There is an ongoing JSR to build a replacement API, but it probably won't be ready for some months yet. JSR 310:
https://jsr-310.dev.java.net/ https://jsr-310.dev.java.net/nonav/doc-2007-11-19/index.html
There are some great threads on the mailing list regarding API design and implementation details (long+int vs. double+double, etc).
https://jsr-310.dev.java.net/servlets/SummarizeList?listName=dev
All that said, what you have for ChucK looks like a good start.
michael
Scott Wheeler
Scott Wheeler wrote:
Here are a couple examples of date / time APIs:
http://doc.trolltech.com/4.3/time.html http://www.boost.org/doc/html/date_time.html
After looking at the Java API for dates and times I found that it delegates things in a way that I found nice.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Date.html http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html
It has separation between a Date, which is basically a unix-epoch timestamp and a calendar class which manages all conversions done on that date (and a separate formatting class for reading and wring dates). Mostly just to see how much work it actually is to extend ChucK's type system I wrote something similar to the Date class, called Timestamp (Time is already taken).
The API is:
Timestamp - int secondsSinceEpoch() - void setSecondsSinceEpoch(int seconds) + Timestamp current() [static]
So, a simple example:
<<< Timestamp.current().secondsSinceEpoch() >>>;
1::second => now;
Timestamp t;
t.setSecondsSinceEpoch(1);
<<< t.secondsSinceEpoch() >>>;
Timestamp.current() @=> t;
<<< t.secondsSinceEpoch() >>>;
Produces:
1195641120 :(int) 1 :(int) 1195641121 :(int)
Random other notes:
- The CVS server isn't responding at the moment. It connects, but diffs don't work, so this is based on the last release.
- ChucK's type system is scattered across quite a few places. On the wishlist-of-things-nobody'll-every-have-time-for would be consolidating (and cleaning it up) a bit. Possibly en route to a 64-bit port since a lot of the type system relies on casts from integers to pointers. (Sidenote there -- would simply using a long long for the t_CKUINT potentially work on 64-bit platforms? May try that later...)
- I tried to follow the current coding style despite difference in taste (or some things that are generally not great C++ practice) so that the code would fit with the rest if the authors want to check it in.
- This may not work on Windows. Should work on Mac and Linux. There's a universal binary (Mac) here:
http://developer.kde.org/~wheeler/files/chuck.gz
-Scott
diff -wur ../../chuck-1.2.1.0-orig/src/chuck_dl.h ./chuck_dl.h --- ../../chuck-1.2.1.0-orig/src/chuck_dl.h 2007-08-23 18:52:47.000000000 +0200 +++ ./chuck_dl.h 2007-11-21 09:17:18.000000000 +0100 @@ -443,6 +443,7 @@ t_CKPOLAR v_polar; Chuck_Object * v_object; Chuck_String * v_string; + Chuck_Timestamp * v_timestamp;
Chuck_DL_Return() { v_complex.re = 0.0; v_complex.im = 0.0; } }; diff -wur ../../chuck-1.2.1.0-orig/src/chuck_lang.cpp ./chuck_lang.cpp --- ../../chuck-1.2.1.0-orig/src/chuck_lang.cpp 2007-08-23 18:52:47.000000000 +0200 +++ ./chuck_lang.cpp 2007-11-21 11:11:43.000000000 +0100 @@ -1432,6 +1430,46 @@ return FALSE; }
+//----------------------------------------------------------------------------- +// name: init_class_Timestamp() +// desc: ... +//----------------------------------------------------------------------------- +t_CKBOOL init_class_Timestamp( Chuck_Env * env, Chuck_Type * type ) +{ + Chuck_DL_Func * func = NULL; + + if( !type_engine_import_class_begin( env, type, env->global(), object_ctor, object_dtor ) ) + return FALSE; + + // add current() + + func = make_new_sfun("Timestamp", "current", Timestamp_current ); + if( !type_engine_import_sfun( env, func ) ) goto error; + + // add secondsSinceEpoch() + + func = make_new_mfun( "int", "secondsSinceEpoch", Timestamp_secondssinceepoch ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add setSecondsSinceEpoch() + + func = make_new_mfun( "void", "setSecondsSinceEpoch", Timestamp_setsecondssinceepoch ); + func->add_arg( "int", "seconds" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // end the class import + + type_engine_import_class_end( env ); + + return TRUE; + +error: + + // end the class import + type_engine_import_class_end( env ); + + return FALSE; +}
// Object ctor CK_DLL_CTOR( object_ctor ) @@ -2824,3 +2896,26 @@ OBJ_MEMBER_TIME(fake_msg, MidiMsg_offset_when) = time; }
+//----------------------------------------------------------------------------- +// Timestamp API +//----------------------------------------------------------------------------- + +CK_DLL_SFUN( Timestamp_current ) +{ + Chuck_Timestamp *time = (Chuck_Timestamp *) instantiate_and_initialize_object( &t_timestamp, SHRED ); + time->setToCurrent(); + RETURN->v_timestamp = time; +} + +CK_DLL_MFUN( Timestamp_secondssinceepoch ) +{ + Chuck_Timestamp *time = (Chuck_Timestamp *) SELF; + RETURN->v_int = (t_CKUINT) time->value; +} + +CK_DLL_MFUN( Timestamp_setsecondssinceepoch ) +{ + Chuck_Timestamp *time = (Chuck_Timestamp *) SELF; + t_CKINT seconds = GET_CK_INT( ARGS ); + time->value = (time_t) seconds; +} diff -wur ../../chuck-1.2.1.0-orig/src/chuck_lang.h ./chuck_lang.h --- ../../chuck-1.2.1.0-orig/src/chuck_lang.h 2007-08-23 18:52:47.000000000 +0200 +++ ./chuck_lang.h 2007-11-21 10:55:10.000000000 +0100 @@ -60,7 +60,7 @@ t_CKBOOL init_class_Midi( Chuck_Env * env ); t_CKBOOL init_class_MidiRW( Chuck_Env * env ); t_CKBOOL init_class_HID( Chuck_Env * env ); - +t_CKBOOL init_class_Timestamp( Chuck_Env * env, Chuck_Type * type );
@@ -357,7 +357,13 @@ CK_DLL_MFUN( HidOut_printerr ); CK_DLL_MFUN( HidOut_send );
- - +//----------------------------------------------------------------------------- +// Timestamp API +//----------------------------------------------------------------------------- +CK_DLL_CTOR( Timestamp_ctor ); +CK_DLL_DTOR( Timestamp_dtor ); +CK_DLL_SFUN( Timestamp_current ); +CK_DLL_MFUN( Timestamp_secondssinceepoch ); +CK_DLL_MFUN( Timestamp_setsecondssinceepoch );
#endif diff -wur ../../chuck-1.2.1.0-orig/src/chuck_oo.h ./chuck_oo.h --- ../../chuck-1.2.1.0-orig/src/chuck_oo.h 2007-08-23 18:52:47.000000000 +0200 +++ ./chuck_oo.h 2007-11-21 09:51:39.000000000 +0100 @@ -343,9 +343,6 @@ std::string str; };
- - - //----------------------------------------------------------------------------- // name: Chuck_IO // desc: base Chuck IO class @@ -463,7 +460,19 @@ std::string m_path; };
+//----------------------------------------------------------------------------- +// name: Chuck_Timestamp +// desc: base Chuck time class +//----------------------------------------------------------------------------- +struct Chuck_Timestamp : Chuck_Object +{ +public: + Chuck_Timestamp() : value( 0 ) { } + ~Chuck_Timestamp() { } + void setToCurrent() { ::time( &value ); }
- +public: + time_t value; +};
#endif diff -wur ../../chuck-1.2.1.0-orig/src/chuck_type.cpp ./chuck_type.cpp --- ../../chuck-1.2.1.0-orig/src/chuck_type.cpp 2007-08-23 18:52:47.000000000 +0200 +++ ./chuck_type.cpp 2007-11-21 10:52:33.000000000 +0100 @@ -69,6 +69,7 @@ Chuck_Type t_fileio( te_fileio, "FileIO", &t_io, sizeof(void *) ); Chuck_Type t_thread( te_thread, "Thread", &t_object, sizeof(void *) ); Chuck_Type t_class( te_class, "Class", &t_object, sizeof(void *) ); +Chuck_Type t_timestamp( te_timestamp, "Timestamp", &t_object, sizeof(void *) );
/* exile struct Chuck_Type t_adc = { te_adc, "adc", &t_ugen, t_ugen.size }; @@ -225,6 +226,7 @@ env->global()->type.add( t_event.name, &t_event ); t_event.lock(); env->global()->type.add( t_io.name, &t_io ); t_io.lock(); env->global()->type.add( t_fileio.name, &t_fileio ); t_fileio.lock(); + env->global()->type.add( t_timestamp.name, &t_timestamp ); t_timestamp.lock();
// dur value t_CKDUR samp = 1.0; @@ -249,6 +251,7 @@ init_class_shred( env, &t_shred ); init_class_event( env, &t_event ); init_class_io( env, &t_io ); + init_class_Timestamp( env, &t_timestamp );
EM_log( CK_LOG_SEVERE, "class 'class'" ); t_class.info = new Chuck_Namespace; diff -wur ../../chuck-1.2.1.0-orig/src/chuck_type.h ./chuck_type.h --- ../../chuck-1.2.1.0-orig/src/chuck_type.h 2007-08-23 18:52:47.000000000 +0200 +++ ./chuck_type.h 2007-11-21 09:20:39.000000000 +0100 @@ -52,7 +52,7 @@ te_complex, te_polar, te_string, te_thread, te_shred, te_class, te_function, te_object, te_user, te_array, te_null, te_ugen, te_uana, te_event, te_void, te_stdout, te_stderr, te_adc, te_dac, te_bunghole, - te_uanablob, te_io, te_fileio, te_multi + te_uanablob, te_io, te_fileio, te_multi, te_timestamp } te_Type;
@@ -811,8 +811,7 @@ extern Chuck_Type t_ugen; extern Chuck_Type t_uana; extern Chuck_Type t_uanablob; - - +extern Chuck_Type t_timestamp;
#endif diff -wur ../../chuck-1.2.1.0-orig/src/ulib_std.cpp ./ulib_std.cpp --- ../../chuck-1.2.1.0-orig/src/ulib_std.cpp 2007-08-23 18:52:47.000000000 +0200 +++ ./ulib_std.cpp 2007-11-21 06:27:59.000000000 +0100 @@ -164,6 +164,10 @@ QUERY->add_sfun( QUERY, fabs_impl, "float", "fabs" ); QUERY->add_arg( QUERY, "float", "value" );
+ // add time + + QUERY->add_sfun( QUERY, time_impl, "int", "time" ); + // add rand QUERY->add_sfun( QUERY, rand_impl, "int", "rand"); //! return int between 0 and RAND_MAX
@@ -527,6 +531,13 @@ //RETURN->v_float = ::fabs( GET_CK_FLOAT(ARGS) ); }
+// time + +CK_DLL_SFUN( time_impl ) +{ + RETURN->v_int = ::time( NULL ); +} + // rand CK_DLL_SFUN( rand_impl ) { diff -wur ../../chuck-1.2.1.0-orig/src/ulib_std.h ./ulib_std.h --- ../../chuck-1.2.1.0-orig/src/ulib_std.h 2007-08-23 18:52:47.000000000 +0200 +++ ./ulib_std.h 2007-11-21 06:29:26.000000000 +0100 @@ -41,6 +41,7 @@ // exports CK_DLL_SFUN( abs_impl ); CK_DLL_SFUN( fabs_impl ); +CK_DLL_SFUN( time_impl ); CK_DLL_SFUN( rand_impl ); CK_DLL_SFUN( randf_impl ); CK_DLL_SFUN( rand2f_impl );
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users