*** empty log message ***
[chuck-blob.git] / v2 / chuck_oo.cpp
blobf5a67bc732cd570330330dd255358aa437b818dc
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: chuck_oo.cpp
27 // desc: ...
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // Ananya Misra (amisra@cs.princeton.edu)
32 // date: Autumn 2004
33 //-----------------------------------------------------------------------------
34 #include "chuck_oo.h"
35 #include "chuck_type.h"
36 #include "chuck_vm.h"
37 #include "chuck_instr.h"
38 #include "chuck_errmsg.h"
40 #include <sstream>
41 #include <iomanip>
42 #include <typeinfo>
43 using namespace std;
46 // initialize
47 t_CKBOOL Chuck_VM_Object::our_locks_in_effect = TRUE;
48 const t_CKINT Chuck_IO::READ = 0x1;
49 const t_CKINT Chuck_IO::WRITE = 0x2;
50 const t_CKINT Chuck_IO::APPEND = 0x4;
51 const t_CKINT Chuck_IO::TRUNCATE = 0x8;
52 const t_CKINT Chuck_IO::ASCII = 0x10;
53 const t_CKINT Chuck_IO::BINARY = 0x20;
58 //-----------------------------------------------------------------------------
59 // name: init_ref()
60 // desc: initialize vm object
61 //-----------------------------------------------------------------------------
62 void Chuck_VM_Object::init_ref()
64 // set reference count
65 m_ref_count = 0;
66 // set flag
67 m_pooled = FALSE;
68 // set to not locked
69 m_locked = FALSE;
70 // set v ref
71 m_v_ref = NULL;
72 // add to vm allocator
73 // Chuck_VM_Alloc::instance()->add_object( this );
79 //-----------------------------------------------------------------------------
80 // name: add_ref()
81 // desc: add reference
82 //-----------------------------------------------------------------------------
83 void Chuck_VM_Object::add_ref()
85 // increment reference count
86 m_ref_count++;
88 // if going from 0 to 1
89 if( m_ref_count == 1 )
91 // add to vm allocator
92 Chuck_VM_Alloc::instance()->add_object( this );
99 //-----------------------------------------------------------------------------
100 // name: release()
101 // desc: remove reference
102 //-----------------------------------------------------------------------------
103 void Chuck_VM_Object::release()
105 // make sure there is at least one reference
106 assert( m_ref_count > 0 );
107 // decrement
108 m_ref_count--;
110 // if no more references
111 if( m_ref_count == 0 )
113 // this is not good
114 if( our_locks_in_effect && m_locked )
116 EM_error2( 0, "internal error: releasing locked VM object!" );
117 // fail
118 assert( FALSE );
119 // in case assert is disabled
120 *(int *)0 = 1;
123 // tell the object manager to set this free
124 Chuck_VM_Alloc::instance()->free_object( this );
131 //-----------------------------------------------------------------------------
132 // name: lock()
133 // desc: lock to keep from deleted
134 //-----------------------------------------------------------------------------
135 void Chuck_VM_Object::lock()
137 m_locked = TRUE;
143 //-----------------------------------------------------------------------------
144 // name: lock_all()
145 // desc: disallow deletion of locked objects
146 //-----------------------------------------------------------------------------
147 void Chuck_VM_Object::lock_all()
149 // log
150 EM_log( CK_LOG_SYSTEM, "locking down special objects..." );
151 // set flag
152 our_locks_in_effect = TRUE;
158 //-----------------------------------------------------------------------------
159 // name: unlock_all()
160 // desc: allow deletion of locked objects (USE WITH CAUTION!)
161 //-----------------------------------------------------------------------------
162 void Chuck_VM_Object::unlock_all()
164 // log
165 EM_log( CK_LOG_SYSTEM, "unprotecting special objects..." );
166 // set flag
167 our_locks_in_effect = FALSE;
173 // static member
174 Chuck_VM_Alloc * Chuck_VM_Alloc::our_instance = NULL;
177 //-----------------------------------------------------------------------------
178 // name: instance()
179 // desc: return static instance
180 //-----------------------------------------------------------------------------
181 Chuck_VM_Alloc * Chuck_VM_Alloc::instance()
183 if( !our_instance )
185 our_instance = new Chuck_VM_Alloc;
186 assert( our_instance != NULL );
189 return our_instance;
195 //-----------------------------------------------------------------------------
196 // name: add_object()
197 // desc: add newly allocated vm object
198 //-----------------------------------------------------------------------------
199 void Chuck_VM_Alloc::add_object( Chuck_VM_Object * obj )
201 // do log
202 if( DO_LOG( CK_LOG_CRAZY ) )
204 // log it
205 EM_log( CK_LOG_CRAZY, "adding '%s' (0x%lx)...",
206 mini_type( typeid(*obj).name() ), obj );
209 // add it to map
215 //-----------------------------------------------------------------------------
216 // name: free_object()
217 // desc: free vm object - reference count should be 0
218 //-----------------------------------------------------------------------------
219 void Chuck_VM_Alloc::free_object( Chuck_VM_Object * obj )
221 // make sure the ref count is 0
222 assert( obj && obj->m_ref_count == 0 );
224 // do log
225 if( DO_LOG( CK_LOG_FINEST ) )
227 // log it
228 EM_log( CK_LOG_FINEST, "freeing '%s' (0x%lx)...",
229 mini_type( typeid(*obj).name() ), obj );
232 // remove it from map
234 // delete it
235 delete obj;
241 //-----------------------------------------------------------------------------
242 // name: Chuck_VM_Alloc()
243 // desc: constructor
244 //-----------------------------------------------------------------------------
245 Chuck_VM_Alloc::Chuck_VM_Alloc()
251 //-----------------------------------------------------------------------------
252 // name: ~Chuck_VM_Alloc()
253 // desc: destructor
254 //-----------------------------------------------------------------------------
255 Chuck_VM_Alloc::~Chuck_VM_Alloc()
261 //-----------------------------------------------------------------------------
262 // name: Chuck_Object()
263 // desc: constructor
264 //-----------------------------------------------------------------------------
265 Chuck_Object::Chuck_Object()
267 // zero virtual table
268 vtable = NULL;
269 // zero type
270 type_ref = NULL;
271 // zero size
272 size = 0;
273 // zero data
274 data = NULL;
276 // add to vm allocator
277 Chuck_VM_Alloc::instance()->add_object( this );
283 //-----------------------------------------------------------------------------
284 // name: Chuck_Object()
285 // desc: ...
286 //-----------------------------------------------------------------------------
287 Chuck_Object::~Chuck_Object()
289 // free
290 if( vtable ) { delete vtable; vtable = NULL; }
291 if( type_ref ) { type_ref->release(); type_ref = NULL; }
292 if( data ) { delete [] data; size = 0; data = NULL; }
298 //-----------------------------------------------------------------------------
299 // name: Chuck_Array4()
300 // desc: constructor
301 //-----------------------------------------------------------------------------
302 Chuck_Array4::Chuck_Array4( t_CKBOOL is_obj, t_CKINT capacity )
304 // sanity check
305 assert( capacity >= 0 );
306 // set size
307 m_vector.resize( capacity );
308 // clear (as non-object, so no releases)
309 m_is_obj = FALSE;
310 this->zero( 0, m_vector.capacity() );
311 // is object (set after clear)
312 m_is_obj = is_obj;
318 //-----------------------------------------------------------------------------
319 // name: ~Chuck_Array4()
320 // desc: destructor
321 //-----------------------------------------------------------------------------
322 Chuck_Array4::~Chuck_Array4()
324 // do nothing
330 //-----------------------------------------------------------------------------
331 // name: addr()
332 // desc: ...
333 //-----------------------------------------------------------------------------
334 t_CKUINT Chuck_Array4::addr( t_CKINT i )
336 // bound check
337 if( i < 0 || i >= m_vector.capacity() )
338 return 0;
340 // get the addr
341 return (t_CKUINT)(&m_vector[i]);
347 //-----------------------------------------------------------------------------
348 // name: addr()
349 // desc: ...
350 //-----------------------------------------------------------------------------
351 t_CKUINT Chuck_Array4::addr( const string & key )
353 // get the addr
354 return (t_CKUINT)(&m_map[key]);
360 //-----------------------------------------------------------------------------
361 // name: get()
362 // desc: ...
363 //-----------------------------------------------------------------------------
364 t_CKINT Chuck_Array4::get( t_CKINT i, t_CKUINT * val )
366 // bound check
367 if( i < 0 || i >= m_vector.capacity() )
368 return 0;
370 // get the value
371 *val = m_vector[i];
373 // return good
374 return 1;
380 //-----------------------------------------------------------------------------
381 // name: get()
382 // desc: ...
383 //-----------------------------------------------------------------------------
384 t_CKINT Chuck_Array4::get( const string & key, t_CKUINT * val )
386 // set to zero
387 *val = 0;
388 // find
389 map<string, t_CKUINT>::iterator iter = m_map.find( key );
390 // check
391 if( iter != m_map.end() ) *val = (*iter).second;
393 // return good
394 return 1;
400 //-----------------------------------------------------------------------------
401 // name: set()
402 // desc: include ref counting
403 //-----------------------------------------------------------------------------
404 t_CKINT Chuck_Array4::set( t_CKINT i, t_CKUINT val )
406 // bound check
407 if( i < 0 || i >= m_vector.capacity() )
408 return 0;
410 t_CKUINT v = m_vector[i];
412 // if obj
413 if( m_is_obj && v ) ((Chuck_Object *)v)->release();
415 // set the value
416 m_vector[i] = val;
418 // if obj
419 if( m_is_obj && val ) ((Chuck_Object *)val)->add_ref();
421 // return good
422 return 1;
429 //-----------------------------------------------------------------------------
430 // name: set()
431 // desc: include ref counting
432 //-----------------------------------------------------------------------------
433 t_CKINT Chuck_Array4::set( const string & key, t_CKUINT val )
435 map<string, t_CKUINT>::iterator iter = m_map.find( key );
437 // if obj
438 if( m_is_obj && iter != m_map.end() )
439 ((Chuck_Object *)(*iter).second)->release();
441 if( !val ) m_map.erase( key );
442 else m_map[key] = val;
444 // if obj
445 if( m_is_obj && val ) ((Chuck_Object *)val)->add_ref();
447 // return good
448 return 1;
454 //-----------------------------------------------------------------------------
455 // name: find()
456 // desc: ...
457 //-----------------------------------------------------------------------------
458 t_CKINT Chuck_Array4::find( const string & key )
460 return m_map.find( key ) != m_map.end();
466 //-----------------------------------------------------------------------------
467 // name: erase()
468 // desc: ...
469 //-----------------------------------------------------------------------------
470 t_CKINT Chuck_Array4::erase( const string & key )
472 map<string, t_CKUINT>::iterator iter = m_map.find( key );
473 t_CKINT v = iter != m_map.end();
475 // if obj
476 if( m_is_obj && iter != m_map.end() )
477 ((Chuck_Object *)(*iter).second)->release();
479 // erase
480 if( v ) m_map.erase( key );
482 return v;
488 //-----------------------------------------------------------------------------
489 // name: push_back()
490 // desc: ...
491 //-----------------------------------------------------------------------------
492 t_CKINT Chuck_Array4::push_back( t_CKUINT val )
494 // TODO: release reference or assume 0?
496 // add to vector
497 m_vector.push_back( val );
499 return 1;
505 //-----------------------------------------------------------------------------
506 // name: pop_back()
507 // desc: ...
508 //-----------------------------------------------------------------------------
509 t_CKINT Chuck_Array4::pop_back( )
511 // check
512 if( m_vector.size() == 0 )
513 return 0;
515 // if obj
516 if( m_is_obj )
518 Chuck_Object * v = (Chuck_Object *)m_vector[m_vector.size()-1];
519 if( v ) v->release();
522 // zero
523 m_vector[m_vector.size()-1] = 0;
524 // add to vector
525 m_vector.pop_back();
527 return 1;
533 //-----------------------------------------------------------------------------
534 // name: back()
535 // desc: ...
536 //-----------------------------------------------------------------------------
537 t_CKINT Chuck_Array4::back( t_CKUINT * val ) const
539 // check
540 if( m_vector.size() == 0 )
541 return 0;
543 // get
544 *val = m_vector.back();
546 return 1;
552 //-----------------------------------------------------------------------------
553 // name: clear()
554 // desc: ...
555 //-----------------------------------------------------------------------------
556 void Chuck_Array4::clear( )
558 // zero
559 zero( 0, m_vector.size() );
561 // clear vector
562 // m_vector.clear();
568 //-----------------------------------------------------------------------------
569 // name: set_capacity()
570 // desc: ...
571 //-----------------------------------------------------------------------------
572 t_CKINT Chuck_Array4::set_capacity( t_CKINT capacity )
574 // sanity check
575 assert( capacity >= 0 );
577 // ensure size
578 set_size( capacity );
580 return m_vector.capacity();
586 //-----------------------------------------------------------------------------
587 // name: set_size()
588 // desc: ...
589 //-----------------------------------------------------------------------------
590 t_CKINT Chuck_Array4::set_size( t_CKINT size )
592 // sanity check
593 assert( size >= 0 );
595 // if clearing size
596 if( size < m_vector.size() )
598 // zero out section
599 zero( size, m_vector.size() );
602 // what the size was
603 t_CKINT size2 = m_vector.size();
604 // resize vector
605 m_vector.resize( size );
607 // if clearing size
608 if( m_vector.size() > size2 )
610 // zero out section
611 zero( size2, m_vector.size() );
614 return m_vector.size();
620 //-----------------------------------------------------------------------------
621 // name: zero()
622 // desc: ...
623 //-----------------------------------------------------------------------------
624 void Chuck_Array4::zero( t_CKUINT start, t_CKUINT end )
626 // sanity check
627 assert( start <= m_vector.capacity() && end <= m_vector.capacity() );
629 // if contains objects
630 if( m_is_obj )
632 Chuck_Object * v = NULL;
633 for( t_CKUINT i = start; i < end; i++ )
635 // get it
636 v = (Chuck_Object *)m_vector[i];
637 // release
638 if( v )
640 v->release();
641 m_vector[i] = 0;
645 else
647 for( t_CKUINT i = start; i < end; i++ )
649 // zero
650 m_vector[i] = 0;
658 //-----------------------------------------------------------------------------
659 // name: Chuck_Array8()
660 // desc: constructor
661 //-----------------------------------------------------------------------------
662 Chuck_Array8::Chuck_Array8( t_CKINT capacity )
664 // sanity check
665 assert( capacity >= 0 );
666 // set size
667 m_vector.resize( capacity );
668 // clear
669 this->zero( 0, m_vector.capacity() );
675 //-----------------------------------------------------------------------------
676 // name: ~Chuck_Array8()
677 // desc: destructor
678 //-----------------------------------------------------------------------------
679 Chuck_Array8::~Chuck_Array8()
681 // do nothing
687 //-----------------------------------------------------------------------------
688 // name: addr()
689 // desc: ...
690 //-----------------------------------------------------------------------------
691 t_CKUINT Chuck_Array8::addr( t_CKINT i )
693 // bound check
694 if( i < 0 || i >= m_vector.capacity() )
695 return 0;
697 // get the addr
698 return (t_CKUINT)(&m_vector[i]);
704 //-----------------------------------------------------------------------------
705 // name: addr()
706 // desc: ...
707 //-----------------------------------------------------------------------------
708 t_CKUINT Chuck_Array8::addr( const string & key )
710 // get the addr
711 return (t_CKUINT)(&m_map[key]);
717 //-----------------------------------------------------------------------------
718 // name: get()
719 // desc: ...
720 //-----------------------------------------------------------------------------
721 t_CKINT Chuck_Array8::get( t_CKINT i, t_CKFLOAT * val )
723 // bound check
724 if( i < 0 || i >= m_vector.capacity() )
725 return 0;
727 // get the value
728 *val = m_vector[i];
730 // return good
731 return 1;
737 //-----------------------------------------------------------------------------
738 // name: get()
739 // desc: ...
740 //-----------------------------------------------------------------------------
741 t_CKINT Chuck_Array8::get( const string & key, t_CKFLOAT * val )
743 // set to zero
744 *val = 0.0;
746 // iterator
747 map<string, t_CKFLOAT>::iterator iter = m_map.find( key );
749 // check
750 if( iter != m_map.end() )
752 // get the value
753 *val = (*iter).second;
756 // return good
757 return 1;
763 //-----------------------------------------------------------------------------
764 // name: set()
765 // desc: ...
766 //-----------------------------------------------------------------------------
767 t_CKINT Chuck_Array8::set( t_CKINT i, t_CKFLOAT val )
769 // bound check
770 if( i < 0 || i >= m_vector.capacity() )
771 return 0;
773 // set the value
774 m_vector[i] = val;
776 // return good
777 return 1;
783 //-----------------------------------------------------------------------------
784 // name: set()
785 // desc: ...
786 //-----------------------------------------------------------------------------
787 t_CKINT Chuck_Array8::set( const string & key, t_CKFLOAT val )
789 map<string, t_CKFLOAT>::iterator iter = m_map.find( key );
791 if( !val ) m_map.erase( key );
792 else m_map[key] = val;
794 // return good
795 return 1;
801 //-----------------------------------------------------------------------------
802 // name: set()
803 // desc: ...
804 //-----------------------------------------------------------------------------
805 t_CKINT Chuck_Array8::find( const string & key )
807 return m_map.find( key ) != m_map.end();
812 //-----------------------------------------------------------------------------
813 // name: set()
814 // desc: ...
815 //-----------------------------------------------------------------------------
816 t_CKINT Chuck_Array8::erase( const string & key )
818 return m_map.erase( key );
824 //-----------------------------------------------------------------------------
825 // name: push_back()
826 // desc: ...
827 //-----------------------------------------------------------------------------
828 t_CKINT Chuck_Array8::push_back( t_CKFLOAT val )
830 // add to vector
831 m_vector.push_back( val );
833 return 1;
839 //-----------------------------------------------------------------------------
840 // name: pop_back()
841 // desc: ...
842 //-----------------------------------------------------------------------------
843 t_CKINT Chuck_Array8::pop_back( )
845 // check
846 if( m_vector.size() == 0 )
847 return 0;
849 // zero
850 m_vector[m_vector.size()-1] = 0.0;
851 // add to vector
852 m_vector.pop_back();
854 return 1;
860 //-----------------------------------------------------------------------------
861 // name: back()
862 // desc: ...
863 //-----------------------------------------------------------------------------
864 t_CKINT Chuck_Array8::back( t_CKFLOAT * val ) const
866 // check
867 if( m_vector.size() == 0 )
868 return 0;
870 // get
871 *val = m_vector.back();
873 return 1;
879 //-----------------------------------------------------------------------------
880 // name: clear()
881 // desc: ...
882 //-----------------------------------------------------------------------------
883 void Chuck_Array8::clear( )
885 // zero
886 zero( 0, m_vector.size() );
888 // clear vector
889 // m_vector.clear();
895 //-----------------------------------------------------------------------------
896 // name: set_capacity()
897 // desc: ...
898 //-----------------------------------------------------------------------------
899 t_CKINT Chuck_Array8::set_capacity( t_CKINT capacity )
901 // sanity check
902 assert( capacity >= 0 );
904 // ensure size
905 set_size( capacity );
907 return m_vector.capacity();
913 //-----------------------------------------------------------------------------
914 // name: set_size()
915 // desc: ...
916 //-----------------------------------------------------------------------------
917 t_CKINT Chuck_Array8::set_size( t_CKINT size )
919 // sanity check
920 assert( size >= 0 );
922 // if clearing size
923 if( size < m_vector.size() )
925 // zero out section
926 zero( size, m_vector.size() );
929 // what the size was
930 t_CKINT size2 = m_vector.size();
931 // resize vector
932 m_vector.resize( size );
934 // if clearing size
935 if( m_vector.size() > size2 )
937 // zero out section
938 zero( size2, m_vector.size() );
941 return m_vector.size();
947 //-----------------------------------------------------------------------------
948 // name: zero()
949 // desc: ...
950 //-----------------------------------------------------------------------------
951 void Chuck_Array8::zero( t_CKUINT start, t_CKUINT end )
953 // sanity check
954 assert( start <= m_vector.capacity() && end <= m_vector.capacity() );
956 for( t_CKUINT i = start; i < end; i++ )
958 // zero
959 m_vector[i] = 0.0;
966 //-----------------------------------------------------------------------------
967 // name: Chuck_Array16()
968 // desc: constructor
969 //-----------------------------------------------------------------------------
970 Chuck_Array16::Chuck_Array16( t_CKINT capacity )
972 // sanity check
973 assert( capacity >= 0 );
974 // set size
975 m_vector.resize( capacity );
976 // clear
977 this->zero( 0, m_vector.capacity() );
983 //-----------------------------------------------------------------------------
984 // name: ~Chuck_Array16()
985 // desc: destructor
986 //-----------------------------------------------------------------------------
987 Chuck_Array16::~Chuck_Array16()
989 // do nothing
995 //-----------------------------------------------------------------------------
996 // name: addr()
997 // desc: ...
998 //-----------------------------------------------------------------------------
999 t_CKUINT Chuck_Array16::addr( t_CKINT i )
1001 // bound check
1002 if( i < 0 || i >= m_vector.capacity() )
1003 return 0;
1005 // get the addr
1006 return (t_CKUINT)(&m_vector[i]);
1012 //-----------------------------------------------------------------------------
1013 // name: addr()
1014 // desc: ...
1015 //-----------------------------------------------------------------------------
1016 t_CKUINT Chuck_Array16::addr( const string & key )
1018 // get the addr
1019 return (t_CKUINT)(&m_map[key]);
1025 //-----------------------------------------------------------------------------
1026 // name: get()
1027 // desc: ...
1028 //-----------------------------------------------------------------------------
1029 t_CKINT Chuck_Array16::get( t_CKINT i, t_CKCOMPLEX * val )
1031 // bound check
1032 if( i < 0 || i >= m_vector.capacity() )
1033 return 0;
1035 // get the value
1036 *val = m_vector[i];
1038 // return good
1039 return 1;
1045 //-----------------------------------------------------------------------------
1046 // name: get()
1047 // desc: ...
1048 //-----------------------------------------------------------------------------
1049 t_CKINT Chuck_Array16::get( const string & key, t_CKCOMPLEX * val )
1051 // set to zero
1052 val->re = 0.0;
1053 val->im = 0.0;
1055 // iterator
1056 map<string, t_CKCOMPLEX>::iterator iter = m_map.find( key );
1058 // check
1059 if( iter != m_map.end() )
1061 // get the value
1062 *val = (*iter).second;
1065 // return good
1066 return 1;
1072 //-----------------------------------------------------------------------------
1073 // name: set()
1074 // desc: ...
1075 //-----------------------------------------------------------------------------
1076 t_CKINT Chuck_Array16::set( t_CKINT i, t_CKCOMPLEX val )
1078 // bound check
1079 if( i < 0 || i >= m_vector.capacity() )
1080 return 0;
1082 // set the value
1083 m_vector[i] = val;
1085 // return good
1086 return 1;
1092 //-----------------------------------------------------------------------------
1093 // name: set()
1094 // desc: ...
1095 //-----------------------------------------------------------------------------
1096 t_CKINT Chuck_Array16::set( const string & key, t_CKCOMPLEX val )
1098 map<string, t_CKCOMPLEX>::iterator iter = m_map.find( key );
1100 if( val.re == 0 && val.im == 0 ) m_map.erase( key );
1101 else m_map[key] = val;
1103 // return good
1104 return 1;
1110 //-----------------------------------------------------------------------------
1111 // name: set()
1112 // desc: ...
1113 //-----------------------------------------------------------------------------
1114 t_CKINT Chuck_Array16::find( const string & key )
1116 return m_map.find( key ) != m_map.end();
1121 //-----------------------------------------------------------------------------
1122 // name: set()
1123 // desc: ...
1124 //-----------------------------------------------------------------------------
1125 t_CKINT Chuck_Array16::erase( const string & key )
1127 return m_map.erase( key );
1133 //-----------------------------------------------------------------------------
1134 // name: push_back()
1135 // desc: ...
1136 //-----------------------------------------------------------------------------
1137 t_CKINT Chuck_Array16::push_back( t_CKCOMPLEX val )
1139 // add to vector
1140 m_vector.push_back( val );
1142 return 1;
1148 //-----------------------------------------------------------------------------
1149 // name: pop_back()
1150 // desc: ...
1151 //-----------------------------------------------------------------------------
1152 t_CKINT Chuck_Array16::pop_back( )
1154 // check
1155 if( m_vector.size() == 0 )
1156 return 0;
1158 // zero
1159 m_vector[m_vector.size()-1].re = 0.0;
1160 m_vector[m_vector.size()-1].im = 0.0;
1161 // add to vector
1162 m_vector.pop_back();
1164 return 1;
1170 //-----------------------------------------------------------------------------
1171 // name: back()
1172 // desc: ...
1173 //-----------------------------------------------------------------------------
1174 t_CKINT Chuck_Array16::back( t_CKCOMPLEX * val ) const
1176 // check
1177 if( m_vector.size() == 0 )
1178 return 0;
1180 // get
1181 *val = m_vector.back();
1183 return 1;
1189 //-----------------------------------------------------------------------------
1190 // name: clear()
1191 // desc: ...
1192 //-----------------------------------------------------------------------------
1193 void Chuck_Array16::clear( )
1195 // zero
1196 zero( 0, m_vector.size() );
1198 // clear vector
1199 // m_vector.clear();
1205 //-----------------------------------------------------------------------------
1206 // name: set_capacity()
1207 // desc: ...
1208 //-----------------------------------------------------------------------------
1209 t_CKINT Chuck_Array16::set_capacity( t_CKINT capacity )
1211 // sanity check
1212 assert( capacity >= 0 );
1214 // ensure size
1215 set_size( capacity );
1217 return m_vector.capacity();
1223 //-----------------------------------------------------------------------------
1224 // name: set_size()
1225 // desc: ...
1226 //-----------------------------------------------------------------------------
1227 t_CKINT Chuck_Array16::set_size( t_CKINT size )
1229 // sanity check
1230 assert( size >= 0 );
1232 // if clearing size
1233 if( size < m_vector.size() )
1235 // zero out section
1236 zero( size, m_vector.size() );
1239 // remember
1240 t_CKINT size2 = m_vector.size();
1241 // resize vector
1242 m_vector.resize( size );
1244 // if clearing size
1245 if( m_vector.size() > size2 )
1247 // zero out section
1248 zero( size2, m_vector.size() );
1251 return m_vector.size();
1257 //-----------------------------------------------------------------------------
1258 // name: zero()
1259 // desc: ...
1260 //-----------------------------------------------------------------------------
1261 void Chuck_Array16::zero( t_CKUINT start, t_CKUINT end )
1263 // sanity check
1264 assert( start <= m_vector.capacity() && end <= m_vector.capacity() );
1266 for( t_CKUINT i = start; i < end; i++ )
1268 // zero
1269 m_vector[i].re = 0.0;
1270 m_vector[i].im = 0.0;
1277 // static
1278 t_CKUINT Chuck_Event::our_can_wait = 0;
1280 //-----------------------------------------------------------------------------
1281 // name: signal()
1282 // desc: signal a event/condition variable, shreduling the next waiting shred
1283 // (if there is one or more)
1284 //-----------------------------------------------------------------------------
1285 void Chuck_Event::signal()
1287 m_queue_lock.acquire();
1288 if( !m_queue.empty() )
1290 Chuck_VM_Shred * shred = m_queue.front();
1291 m_queue.pop();
1292 m_queue_lock.release();
1293 Chuck_VM_Shreduler * shreduler = shred->vm_ref->shreduler();
1294 shred->event = NULL;
1295 shreduler->remove_blocked( shred );
1296 shreduler->shredule( shred );
1297 // push the current time
1298 t_CKTIME *& sp = (t_CKTIME *&)shred->reg->sp;
1299 push_( sp, shreduler->now_system );
1301 else
1302 m_queue_lock.release();
1308 //-----------------------------------------------------------------------------
1309 // name: remove()
1310 // desc: remove a shred from the event queue.
1311 //-----------------------------------------------------------------------------
1312 t_CKBOOL Chuck_Event::remove( Chuck_VM_Shred * shred )
1314 queue<Chuck_VM_Shred *> temp;
1315 t_CKBOOL removed = FALSE;
1316 m_queue_lock.acquire();
1317 while( !m_queue.empty() )
1319 if( m_queue.front() != shred )
1320 temp.push( m_queue.front() );
1321 else {
1322 shred->event = NULL;
1323 removed = TRUE;
1325 m_queue.pop();
1328 m_queue = temp;
1329 m_queue_lock.release();
1330 return removed;
1336 //-----------------------------------------------------------------------------
1337 // name: queue_broadcast()
1338 // desc: queue the event to broadcast a event/condition variable, by the owner
1339 // of the queue
1340 //-----------------------------------------------------------------------------
1341 void Chuck_Event::queue_broadcast()
1343 // TODO: handle multiple VM
1344 m_queue_lock.acquire();
1345 if( !m_queue.empty() )
1347 Chuck_VM_Shred * shred = m_queue.front();
1348 m_queue_lock.release();
1349 shred->vm_ref->queue_event( this, 1 );
1351 else
1352 m_queue_lock.release();
1359 //-----------------------------------------------------------------------------
1360 // name: broadcast()
1361 // desc: broadcast a event/condition variable, shreduling all waiting shreds
1362 //-----------------------------------------------------------------------------
1363 void Chuck_Event::broadcast()
1365 m_queue_lock.acquire();
1366 while( !m_queue.empty() )
1368 m_queue_lock.release();
1369 this->signal();
1370 m_queue_lock.acquire();
1372 m_queue_lock.release();
1378 //-----------------------------------------------------------------------------
1379 // name: wait()
1380 // desc: cause event/condition variable to block the current shred, putting it
1381 // on its waiting list, and suspennd the shred from the VM.
1382 //-----------------------------------------------------------------------------
1383 void Chuck_Event::wait( Chuck_VM_Shred * shred, Chuck_VM * vm )
1385 EM_log( CK_LOG_FINE, "shred '%d' wait on event '%x'...", shred->xid, (t_CKUINT)this );
1386 // make sure the shred info matches the vm
1387 assert( shred->vm_ref == vm );
1389 Chuck_DL_Return RETURN;
1390 f_mfun canwaitplease = (f_mfun)this->vtable->funcs[our_can_wait]->code->native_func;
1391 canwaitplease( this, NULL, &RETURN, shred ); // TODO: check this is right shred
1392 // RETURN.v_int = 1;
1394 // see if we can wait
1395 if( RETURN.v_int )
1397 // suspend
1398 shred->is_running = FALSE;
1400 // add to waiting list
1401 m_queue_lock.acquire();
1402 m_queue.push( shred );
1403 m_queue_lock.release();
1405 // add event to shred
1406 assert( shred->event == NULL );
1407 shred->event = this;
1409 // add shred to shreduler
1410 vm->shreduler()->add_blocked( shred );
1412 else // can't wait
1414 // push the current time
1415 t_CKTIME *& sp = (t_CKTIME *&)shred->reg->sp;
1416 push_( sp, shred->now );
1423 //-----------------------------------------------------------------------------
1424 // name:
1425 // desc:
1426 //-----------------------------------------------------------------------------
1427 Chuck_IO::Chuck_IO()
1433 //-----------------------------------------------------------------------------
1434 // name:
1435 // desc:
1436 //-----------------------------------------------------------------------------
1437 Chuck_IO::~Chuck_IO()
1443 //-----------------------------------------------------------------------------
1444 // name:
1445 // desc:
1446 //-----------------------------------------------------------------------------
1447 Chuck_IO_File * Chuck_IO::openFile( const string & path, t_CKINT flags )
1449 return NULL;
1455 //-----------------------------------------------------------------------------
1456 // name:
1457 // desc:
1458 //-----------------------------------------------------------------------------
1459 string Chuck_IO::currentDir()
1461 return "";
1467 //-----------------------------------------------------------------------------
1468 // name:
1469 // desc:
1470 //-----------------------------------------------------------------------------
1471 string Chuck_IO::changeDir( const string & to )
1473 return "";
1479 //-----------------------------------------------------------------------------
1480 // name:
1481 // desc:
1482 //-----------------------------------------------------------------------------
1483 t_CKBOOL Chuck_IO::isFile( const string & path )
1485 return FALSE;
1491 //-----------------------------------------------------------------------------
1492 // name:
1493 // desc:
1494 //-----------------------------------------------------------------------------
1495 t_CKBOOL Chuck_IO::isDir( const string & path )
1497 return FALSE;
1503 //-----------------------------------------------------------------------------
1504 // name:
1505 // desc:
1506 //-----------------------------------------------------------------------------
1507 t_CKINT Chuck_IO::getSize( const string & path )
1509 return 0;
1515 //-----------------------------------------------------------------------------
1516 // name:
1517 // desc:
1518 //-----------------------------------------------------------------------------
1519 string Chuck_IO::baseName( const string & path )
1521 return "";
1527 //-----------------------------------------------------------------------------
1528 // name:
1529 // desc:
1530 //-----------------------------------------------------------------------------
1531 void Chuck_IO::getContent( vector<string> & content )
1533 content.clear();
1539 //-----------------------------------------------------------------------------
1540 // name: Chuck_IO_File()
1541 // desc: constructor
1542 //-----------------------------------------------------------------------------
1543 Chuck_IO_File::Chuck_IO_File()
1545 // zero things out
1546 m_ready_flags = 0;
1547 m_flags = 0;
1553 //-----------------------------------------------------------------------------
1554 // name: ~Chuck_IO_File()
1555 // desc: destructor
1556 //-----------------------------------------------------------------------------
1557 Chuck_IO_File::~Chuck_IO_File()
1559 // check it
1560 this->close();
1566 //-----------------------------------------------------------------------------
1567 // name: open
1568 // desc: open file from disk
1569 //-----------------------------------------------------------------------------
1570 t_CKBOOL Chuck_IO_File::open( const string & path, t_CKINT flags )
1572 // close first
1573 this->close();
1575 // log
1576 EM_log( CK_LOG_INFO, "(IO): opening file from disk..." );
1577 EM_pushlog();
1578 EM_log( CK_LOG_INFO, "(IO): path: %s", path.c_str() );
1579 EM_log( CK_LOG_INFO, "(IO): READ: %s WRITE: %s APPEND: %s PLUS: %s",
1580 flags & Chuck_IO::READ ? "Y" : "N", flags & Chuck_IO::WRITE ? "Y" : "N",
1581 flags & Chuck_IO::APPEND ? "Y" : "N", flags & Chuck_IO::TRUNCATE ? "Y" : "N",
1582 flags & Chuck_IO::BINARY ? "Y" : "N" );
1584 // open modes
1585 int nMode = 0;
1587 // construct mode string
1588 stringstream sout;
1589 if( flags & Chuck_IO::READ )
1591 // write it
1592 sout << "r";
1593 // set ready
1594 m_ready_flags |= Chuck_IO::READ;
1595 // set mode
1596 nMode |= ios::in;
1598 if( flags & Chuck_IO::WRITE )
1600 // write it
1601 sout << "w";
1602 // set ready
1603 m_ready_flags |= Chuck_IO::WRITE;
1604 // set mode
1605 nMode |= ios::out;
1607 if( flags & Chuck_IO::APPEND )
1609 // write it
1610 sout << "a";
1611 // set ready
1612 m_ready_flags |= Chuck_IO::WRITE | Chuck_IO::APPEND;
1613 // set mode
1614 nMode |= ios::out | ios::ate;
1616 if( flags & Chuck_IO::TRUNCATE )
1618 // read + write
1619 if( flags ^ Chuck_IO::WRITE || flags & Chuck_IO::APPEND )
1621 // error
1622 EM_error3( "(FileIO): malformed open flag (TRUNCATE)..." );
1623 EM_error3( " note: must be used with WRITE, and without APPEND" );
1624 goto error;
1627 // write it
1628 sout << "w";
1629 // set ready
1630 m_ready_flags |= Chuck_IO::TRUNCATE;
1631 // set mode
1632 nMode |= ios::trunc;
1634 if( flags & Chuck_IO::BINARY )
1636 // add it
1637 m_ready_flags |= Chuck_IO::BINARY;
1640 // sanity check
1641 if( sout.str().length() == 0 )
1643 // error
1644 EM_error3( "(FileIO): malformed open flag (no operation specified)..." );
1645 goto error;
1648 // log
1649 EM_log( CK_LOG_INFO, "(IO): flag: '%s'", sout.str().c_str() );
1651 // windows sucks for being creative in the wrong places
1652 #ifdef __PLATFORM_WIN32__
1653 // if( flags ^ Chuck_IO::TRUNCATE && flags | Chuck_IO::READ ) nMode |= ios::nocreate;
1654 m_io.open( path.c_str(), nMode );
1655 #else
1656 m_io.open( path.c_str(), (_Ios_Openmode)nMode );
1657 #endif
1659 // check for error
1660 if( !m_io.good() )
1662 EM_error3( "(FileIO): cannot open file: '%s'", path.c_str() );
1663 goto error;
1666 // for write
1667 if( good2write() )
1669 // set precision
1670 setprecision( 6 );
1673 // set path
1674 m_path = path;
1675 // set flags
1676 m_flags = flags;
1678 // pop
1679 EM_poplog();
1681 return TRUE;
1683 error:
1685 // pop
1686 EM_poplog();
1688 // reset
1689 m_ready_flags = 0;
1690 // reset
1691 m_path = "";
1693 return FALSE;
1699 //-----------------------------------------------------------------------------
1700 // name: close
1701 // desc: close file
1702 //-----------------------------------------------------------------------------
1703 t_CKBOOL Chuck_IO_File::close()
1705 // check
1706 if( !m_io.good() )
1707 return FALSE;
1709 // log
1710 EM_log( CK_LOG_INFO, "(IO): closing file '%s'...", m_path.c_str() );
1711 // close it
1712 m_io.close();
1713 m_flags = 0;
1714 m_ready_flags = 0;
1715 m_path = "";
1717 return TRUE;
1723 //-----------------------------------------------------------------------------
1724 // name: more()
1725 // desc: is there more to read?
1726 //-----------------------------------------------------------------------------
1727 t_CKBOOL Chuck_IO_File::more()
1729 return !eof();
1735 //-----------------------------------------------------------------------------
1736 // name: eof()
1737 // desc: end of file?
1738 //-----------------------------------------------------------------------------
1739 t_CKBOOL Chuck_IO_File::eof()
1741 // sanity
1742 if( !m_io.good() ) return TRUE;
1743 return !m_io;
1749 //-----------------------------------------------------------------------------
1750 // name: good2read()
1751 // desc: ready to read?
1752 //-----------------------------------------------------------------------------
1753 t_CKBOOL Chuck_IO_File::good2read()
1755 return ( m_io.good() && m_flags & Chuck_IO::READ );
1761 //-----------------------------------------------------------------------------
1762 // name: good2write()
1763 // desc: ready for write?
1764 //-----------------------------------------------------------------------------
1765 t_CKBOOL Chuck_IO_File::good2write()
1767 return ( m_io.good() && m_flags & Chuck_IO::READ );
1773 //-----------------------------------------------------------------------------
1774 // name: readInt()
1775 // desc: read next as (ascii) integer
1776 //-----------------------------------------------------------------------------
1777 t_CKINT Chuck_IO_File::readInt()
1779 // sanity
1780 if( !good2read() ) return 0;
1782 // read int
1783 t_CKINT val = 0;
1784 // TODO: check for EOF?
1785 m_io >> val;
1787 return val;
1793 //-----------------------------------------------------------------------------
1794 // name: readFloat()
1795 // desc: read next as (ascii) floating point value
1796 //-----------------------------------------------------------------------------
1797 t_CKFLOAT Chuck_IO_File::readFloat()
1799 // sanity
1800 if( !good2read() ) return 0;
1802 // read float
1803 t_CKFLOAT val = 0;
1804 // TODO: check for EOF?
1805 m_io >> val;
1807 return 0;
1813 //-----------------------------------------------------------------------------
1814 // name: readString()
1815 // desc: read next as string
1816 //-----------------------------------------------------------------------------
1817 string Chuck_IO_File::readString()
1819 // sanity
1820 if( !good2read() ) return 0;
1822 // read string
1823 string val;
1824 // TODO: check for EOF?
1825 m_io >> val;
1827 return val;
1833 //-----------------------------------------------------------------------------
1834 // name: readLine()
1835 // desc: read line
1836 //-----------------------------------------------------------------------------
1837 string Chuck_IO_File::readLine()
1839 // sanity
1840 if( !good2read() ) return 0;
1842 // read string
1843 string val;
1844 // TODO: check for EOF?
1845 std::getline( m_io, val );
1847 return val;
1853 //-----------------------------------------------------------------------------
1854 // name: writeInt()
1855 // desc: write (ascii) integer
1856 //-----------------------------------------------------------------------------
1857 t_CKBOOL Chuck_IO_File::writeInt( t_CKINT val )
1859 // sanity
1860 if( !good2write() ) return FALSE;
1862 // write it
1863 m_io << val;
1865 return m_io.good();
1871 //-----------------------------------------------------------------------------
1872 // name: writeFloat()
1873 // desc: write (ascii) floating point value
1874 //-----------------------------------------------------------------------------
1875 t_CKBOOL Chuck_IO_File::writeFloat( t_CKFLOAT val )
1877 // sanity
1878 if( !good2write() ) return 0;
1880 // write it
1881 m_io << val;
1883 return m_io.good();
1889 //-----------------------------------------------------------------------------
1890 // name: writeString()
1891 // desc: write string
1892 //-----------------------------------------------------------------------------
1893 t_CKBOOL Chuck_IO_File::writeString( const string & val )
1895 // sanity
1896 if( !good2read() ) return 0;
1898 // write it
1899 m_io << val;
1901 return m_io.good();
1907 //-----------------------------------------------------------------------------
1908 // name: writeLine()
1909 // desc: write line
1910 //-----------------------------------------------------------------------------
1911 t_CKBOOL Chuck_IO_File::writeLine( const string & val )
1913 // sanity
1914 if( !good2read() ) return 0;
1916 // write it
1917 m_io << val << endl;
1919 return m_io.good();
1926 //-----------------------------------------------------------------------------
1927 // name: read32i()
1928 // desc: read next 32 bits, return as int
1929 //-----------------------------------------------------------------------------
1930 t_CKINT Chuck_IO_File::read32i()
1932 return 0;
1938 //-----------------------------------------------------------------------------
1939 // name: read24i()
1940 // desc: read next 24 bits, return as int
1941 //-----------------------------------------------------------------------------
1942 t_CKINT Chuck_IO_File::read24i()
1944 return 0;
1950 //-----------------------------------------------------------------------------
1951 // name: read16i()
1952 // desc: read next 16 bits, return as int
1953 //-----------------------------------------------------------------------------
1954 t_CKINT Chuck_IO_File::read16i()
1956 return 0;
1962 //-----------------------------------------------------------------------------
1963 // name: read8i()
1964 // desc: return next 8 bits, return as int
1965 //-----------------------------------------------------------------------------
1966 t_CKINT Chuck_IO_File::read8i()
1968 return 0;
1974 //-----------------------------------------------------------------------------
1975 // name: read32f()
1976 // desc: return next 32-bits as (binary) single float
1977 //-----------------------------------------------------------------------------
1978 t_CKSINGLE Chuck_IO_File::read32f()
1980 return 0;
1986 //-----------------------------------------------------------------------------
1987 // name: read64f()
1988 // desc: return next 64-bits as (binary) double float
1989 //-----------------------------------------------------------------------------
1990 t_CKDOUBLE Chuck_IO_File::read64f()
1992 return 0;