*** empty log message ***
[chuck-blob.git] / v2 / chuck_oo.cpp
blobb16d545ebd40857be4b0cb9a514b470054922a27
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 capacity
307 m_vector.reserve( capacity );
308 // set size
309 m_vector.resize( capacity );
310 // clear (as non-object, so no releases)
311 m_is_obj = FALSE;
312 this->zero( 0, m_vector.capacity() );
313 // is object (set after clear)
314 m_is_obj = is_obj;
320 //-----------------------------------------------------------------------------
321 // name: ~Chuck_Array4()
322 // desc: destructor
323 //-----------------------------------------------------------------------------
324 Chuck_Array4::~Chuck_Array4()
326 // do nothing
332 //-----------------------------------------------------------------------------
333 // name: addr()
334 // desc: ...
335 //-----------------------------------------------------------------------------
336 t_CKUINT Chuck_Array4::addr( t_CKINT i )
338 // bound check
339 if( i < 0 || i >= m_vector.capacity() )
340 return 0;
342 // get the addr
343 return (t_CKUINT)(&m_vector[i]);
349 //-----------------------------------------------------------------------------
350 // name: addr()
351 // desc: ...
352 //-----------------------------------------------------------------------------
353 t_CKUINT Chuck_Array4::addr( const string & key )
355 // get the addr
356 return (t_CKUINT)(&m_map[key]);
362 //-----------------------------------------------------------------------------
363 // name: get()
364 // desc: ...
365 //-----------------------------------------------------------------------------
366 t_CKINT Chuck_Array4::get( t_CKINT i, t_CKUINT * val )
368 // bound check
369 if( i < 0 || i >= m_vector.capacity() )
370 return 0;
372 // get the value
373 *val = m_vector[i];
375 // return good
376 return 1;
382 //-----------------------------------------------------------------------------
383 // name: get()
384 // desc: ...
385 //-----------------------------------------------------------------------------
386 t_CKINT Chuck_Array4::get( const string & key, t_CKUINT * val )
388 // set to zero
389 *val = 0;
390 // find
391 map<string, t_CKUINT>::iterator iter = m_map.find( key );
392 // check
393 if( iter != m_map.end() ) *val = (*iter).second;
395 // return good
396 return 1;
402 //-----------------------------------------------------------------------------
403 // name: set()
404 // desc: include ref counting
405 //-----------------------------------------------------------------------------
406 t_CKINT Chuck_Array4::set( t_CKINT i, t_CKUINT val )
408 // bound check
409 if( i < 0 || i >= m_vector.capacity() )
410 return 0;
412 t_CKUINT v = m_vector[i];
414 // if obj
415 if( m_is_obj && v ) ((Chuck_Object *)v)->release();
417 // set the value
418 m_vector[i] = val;
420 // if obj
421 if( m_is_obj && val ) ((Chuck_Object *)val)->add_ref();
423 // return good
424 return 1;
431 //-----------------------------------------------------------------------------
432 // name: set()
433 // desc: include ref counting
434 //-----------------------------------------------------------------------------
435 t_CKINT Chuck_Array4::set( const string & key, t_CKUINT val )
437 map<string, t_CKUINT>::iterator iter = m_map.find( key );
439 // if obj
440 if( m_is_obj && iter != m_map.end() )
441 ((Chuck_Object *)(*iter).second)->release();
443 if( !val ) m_map.erase( key );
444 else m_map[key] = val;
446 // if obj
447 if( m_is_obj && val ) ((Chuck_Object *)val)->add_ref();
449 // return good
450 return 1;
456 //-----------------------------------------------------------------------------
457 // name: find()
458 // desc: ...
459 //-----------------------------------------------------------------------------
460 t_CKINT Chuck_Array4::find( const string & key )
462 return m_map.find( key ) != m_map.end();
468 //-----------------------------------------------------------------------------
469 // name: erase()
470 // desc: ...
471 //-----------------------------------------------------------------------------
472 t_CKINT Chuck_Array4::erase( const string & key )
474 map<string, t_CKUINT>::iterator iter = m_map.find( key );
475 t_CKINT v = iter != m_map.end();
477 // if obj
478 if( m_is_obj && iter != m_map.end() )
479 ((Chuck_Object *)(*iter).second)->release();
481 // erase
482 if( v ) m_map.erase( key );
484 return v;
490 //-----------------------------------------------------------------------------
491 // name: push_back()
492 // desc: ...
493 //-----------------------------------------------------------------------------
494 t_CKINT Chuck_Array4::push_back( t_CKUINT val )
496 // TODO: release reference or assume 0?
498 // add to vector
499 m_vector.push_back( val );
501 return 1;
507 //-----------------------------------------------------------------------------
508 // name: pop_back()
509 // desc: ...
510 //-----------------------------------------------------------------------------
511 t_CKINT Chuck_Array4::pop_back( )
513 // check
514 if( m_vector.size() == 0 )
515 return 0;
517 // if obj
518 if( m_is_obj )
520 Chuck_Object * v = (Chuck_Object *)m_vector[m_vector.size()-1];
521 if( v ) v->release();
524 // zero
525 m_vector[m_vector.size()-1] = 0;
526 // add to vector
527 m_vector.pop_back();
529 return 1;
535 //-----------------------------------------------------------------------------
536 // name: back()
537 // desc: ...
538 //-----------------------------------------------------------------------------
539 t_CKINT Chuck_Array4::back( t_CKUINT * val ) const
541 // check
542 if( m_vector.size() == 0 )
543 return 0;
545 // get
546 *val = m_vector.back();
548 return 1;
554 //-----------------------------------------------------------------------------
555 // name: clear()
556 // desc: ...
557 //-----------------------------------------------------------------------------
558 void Chuck_Array4::clear( )
560 // zero
561 zero( 0, m_vector.size() );
563 // clear vector
564 m_vector.clear();
570 //-----------------------------------------------------------------------------
571 // name: set_capacity()
572 // desc: ...
573 //-----------------------------------------------------------------------------
574 t_CKINT Chuck_Array4::set_capacity( t_CKINT capacity )
576 // sanity check
577 assert( capacity >= 0 );
579 // if clearing capacity
580 if( capacity < m_vector.size() )
582 // zero out section
583 set_size( capacity );
586 // resize vector
587 m_vector.reserve( capacity );
589 return m_vector.capacity();
595 //-----------------------------------------------------------------------------
596 // name: set_size()
597 // desc: ...
598 //-----------------------------------------------------------------------------
599 t_CKINT Chuck_Array4::set_size( t_CKINT size )
601 // sanity check
602 assert( size >= 0 );
604 // if clearing size
605 if( size < m_vector.size() )
607 // zero out section
608 zero( size, m_vector.size() );
611 // resize vector
612 m_vector.resize( 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 capacity
667 m_vector.reserve( capacity );
668 // set size
669 m_vector.resize( capacity );
670 // clear
671 this->zero( 0, m_vector.capacity() );
677 //-----------------------------------------------------------------------------
678 // name: ~Chuck_Array8()
679 // desc: destructor
680 //-----------------------------------------------------------------------------
681 Chuck_Array8::~Chuck_Array8()
683 // do nothing
689 //-----------------------------------------------------------------------------
690 // name: addr()
691 // desc: ...
692 //-----------------------------------------------------------------------------
693 t_CKUINT Chuck_Array8::addr( t_CKINT i )
695 // bound check
696 if( i < 0 || i >= m_vector.capacity() )
697 return 0;
699 // get the addr
700 return (t_CKUINT)(&m_vector[i]);
706 //-----------------------------------------------------------------------------
707 // name: addr()
708 // desc: ...
709 //-----------------------------------------------------------------------------
710 t_CKUINT Chuck_Array8::addr( const string & key )
712 // get the addr
713 return (t_CKUINT)(&m_map[key]);
719 //-----------------------------------------------------------------------------
720 // name: get()
721 // desc: ...
722 //-----------------------------------------------------------------------------
723 t_CKINT Chuck_Array8::get( t_CKINT i, t_CKFLOAT * val )
725 // bound check
726 if( i < 0 || i >= m_vector.capacity() )
727 return 0;
729 // get the value
730 *val = m_vector[i];
732 // return good
733 return 1;
739 //-----------------------------------------------------------------------------
740 // name: get()
741 // desc: ...
742 //-----------------------------------------------------------------------------
743 t_CKINT Chuck_Array8::get( const string & key, t_CKFLOAT * val )
745 // set to zero
746 *val = 0.0;
748 // iterator
749 map<string, t_CKFLOAT>::iterator iter = m_map.find( key );
751 // check
752 if( iter != m_map.end() )
754 // get the value
755 *val = (*iter).second;
758 // return good
759 return 1;
765 //-----------------------------------------------------------------------------
766 // name: set()
767 // desc: ...
768 //-----------------------------------------------------------------------------
769 t_CKINT Chuck_Array8::set( t_CKINT i, t_CKFLOAT val )
771 // bound check
772 if( i < 0 || i >= m_vector.capacity() )
773 return 0;
775 // set the value
776 m_vector[i] = val;
778 // return good
779 return 1;
785 //-----------------------------------------------------------------------------
786 // name: set()
787 // desc: ...
788 //-----------------------------------------------------------------------------
789 t_CKINT Chuck_Array8::set( const string & key, t_CKFLOAT val )
791 map<string, t_CKFLOAT>::iterator iter = m_map.find( key );
793 if( !val ) m_map.erase( key );
794 else m_map[key] = val;
796 // return good
797 return 1;
803 //-----------------------------------------------------------------------------
804 // name: set()
805 // desc: ...
806 //-----------------------------------------------------------------------------
807 t_CKINT Chuck_Array8::find( const string & key )
809 return m_map.find( key ) != m_map.end();
814 //-----------------------------------------------------------------------------
815 // name: set()
816 // desc: ...
817 //-----------------------------------------------------------------------------
818 t_CKINT Chuck_Array8::erase( const string & key )
820 return m_map.erase( key );
826 //-----------------------------------------------------------------------------
827 // name: push_back()
828 // desc: ...
829 //-----------------------------------------------------------------------------
830 t_CKINT Chuck_Array8::push_back( t_CKFLOAT val )
832 // add to vector
833 m_vector.push_back( val );
835 return 1;
841 //-----------------------------------------------------------------------------
842 // name: pop_back()
843 // desc: ...
844 //-----------------------------------------------------------------------------
845 t_CKINT Chuck_Array8::pop_back( )
847 // check
848 if( m_vector.size() == 0 )
849 return 0;
851 // zero
852 m_vector[m_vector.size()-1] = 0.0;
853 // add to vector
854 m_vector.pop_back();
856 return 1;
862 //-----------------------------------------------------------------------------
863 // name: back()
864 // desc: ...
865 //-----------------------------------------------------------------------------
866 t_CKINT Chuck_Array8::back( t_CKFLOAT * val ) const
868 // check
869 if( m_vector.size() == 0 )
870 return 0;
872 // get
873 *val = m_vector.back();
875 return 1;
881 //-----------------------------------------------------------------------------
882 // name: clear()
883 // desc: ...
884 //-----------------------------------------------------------------------------
885 void Chuck_Array8::clear( )
887 // zero
888 zero( 0, m_vector.size() );
890 // clear vector
891 m_vector.clear();
897 //-----------------------------------------------------------------------------
898 // name: set_capacity()
899 // desc: ...
900 //-----------------------------------------------------------------------------
901 t_CKINT Chuck_Array8::set_capacity( t_CKINT capacity )
903 // sanity check
904 assert( capacity >= 0 );
906 // if less
907 if( capacity < m_vector.size() )
908 set_size( capacity );
910 // resize vector
911 m_vector.reserve( capacity );
913 return m_vector.capacity();
919 //-----------------------------------------------------------------------------
920 // name: set_size()
921 // desc: ...
922 //-----------------------------------------------------------------------------
923 t_CKINT Chuck_Array8::set_size( t_CKINT size )
925 // sanity check
926 assert( size >= 0 );
928 // if clearing size
929 if( size < m_vector.size() )
931 // zero out section
932 zero( size, m_vector.size() );
935 // resize vector
936 m_vector.resize( size );
938 return m_vector.size();
944 //-----------------------------------------------------------------------------
945 // name: zero()
946 // desc: ...
947 //-----------------------------------------------------------------------------
948 void Chuck_Array8::zero( t_CKUINT start, t_CKUINT end )
950 // sanity check
951 assert( start <= m_vector.capacity() && end <= m_vector.capacity() );
953 for( t_CKUINT i = start; i < end; i++ )
955 // zero
956 m_vector[i] = 0.0;
963 //-----------------------------------------------------------------------------
964 // name: Chuck_Array16()
965 // desc: constructor
966 //-----------------------------------------------------------------------------
967 Chuck_Array16::Chuck_Array16( t_CKINT capacity )
969 // sanity check
970 assert( capacity >= 0 );
971 // set capacity
972 m_vector.reserve( capacity );
973 // set size
974 m_vector.resize( capacity );
975 // clear
976 this->zero( 0, m_vector.capacity() );
982 //-----------------------------------------------------------------------------
983 // name: ~Chuck_Array16()
984 // desc: destructor
985 //-----------------------------------------------------------------------------
986 Chuck_Array16::~Chuck_Array16()
988 // do nothing
994 //-----------------------------------------------------------------------------
995 // name: addr()
996 // desc: ...
997 //-----------------------------------------------------------------------------
998 t_CKUINT Chuck_Array16::addr( t_CKINT i )
1000 // bound check
1001 if( i < 0 || i >= m_vector.capacity() )
1002 return 0;
1004 // get the addr
1005 return (t_CKUINT)(&m_vector[i]);
1011 //-----------------------------------------------------------------------------
1012 // name: addr()
1013 // desc: ...
1014 //-----------------------------------------------------------------------------
1015 t_CKUINT Chuck_Array16::addr( const string & key )
1017 // get the addr
1018 return (t_CKUINT)(&m_map[key]);
1024 //-----------------------------------------------------------------------------
1025 // name: get()
1026 // desc: ...
1027 //-----------------------------------------------------------------------------
1028 t_CKINT Chuck_Array16::get( t_CKINT i, t_CKCOMPLEX * val )
1030 // bound check
1031 if( i < 0 || i >= m_vector.capacity() )
1032 return 0;
1034 // get the value
1035 *val = m_vector[i];
1037 // return good
1038 return 1;
1044 //-----------------------------------------------------------------------------
1045 // name: get()
1046 // desc: ...
1047 //-----------------------------------------------------------------------------
1048 t_CKINT Chuck_Array16::get( const string & key, t_CKCOMPLEX * val )
1050 // set to zero
1051 val->re = 0.0;
1052 val->im = 0.0;
1054 // iterator
1055 map<string, t_CKCOMPLEX>::iterator iter = m_map.find( key );
1057 // check
1058 if( iter != m_map.end() )
1060 // get the value
1061 *val = (*iter).second;
1064 // return good
1065 return 1;
1071 //-----------------------------------------------------------------------------
1072 // name: set()
1073 // desc: ...
1074 //-----------------------------------------------------------------------------
1075 t_CKINT Chuck_Array16::set( t_CKINT i, t_CKCOMPLEX val )
1077 // bound check
1078 if( i < 0 || i >= m_vector.capacity() )
1079 return 0;
1081 // set the value
1082 m_vector[i] = val;
1084 // return good
1085 return 1;
1091 //-----------------------------------------------------------------------------
1092 // name: set()
1093 // desc: ...
1094 //-----------------------------------------------------------------------------
1095 t_CKINT Chuck_Array16::set( const string & key, t_CKCOMPLEX val )
1097 map<string, t_CKCOMPLEX>::iterator iter = m_map.find( key );
1099 if( val.re == 0 && val.im == 0 ) m_map.erase( key );
1100 else m_map[key] = val;
1102 // return good
1103 return 1;
1109 //-----------------------------------------------------------------------------
1110 // name: set()
1111 // desc: ...
1112 //-----------------------------------------------------------------------------
1113 t_CKINT Chuck_Array16::find( const string & key )
1115 return m_map.find( key ) != m_map.end();
1120 //-----------------------------------------------------------------------------
1121 // name: set()
1122 // desc: ...
1123 //-----------------------------------------------------------------------------
1124 t_CKINT Chuck_Array16::erase( const string & key )
1126 return m_map.erase( key );
1132 //-----------------------------------------------------------------------------
1133 // name: push_back()
1134 // desc: ...
1135 //-----------------------------------------------------------------------------
1136 t_CKINT Chuck_Array16::push_back( t_CKCOMPLEX val )
1138 // add to vector
1139 m_vector.push_back( val );
1141 return 1;
1147 //-----------------------------------------------------------------------------
1148 // name: pop_back()
1149 // desc: ...
1150 //-----------------------------------------------------------------------------
1151 t_CKINT Chuck_Array16::pop_back( )
1153 // check
1154 if( m_vector.size() == 0 )
1155 return 0;
1157 // zero
1158 m_vector[m_vector.size()-1].re = 0.0;
1159 m_vector[m_vector.size()-1].im = 0.0;
1160 // add to vector
1161 m_vector.pop_back();
1163 return 1;
1169 //-----------------------------------------------------------------------------
1170 // name: back()
1171 // desc: ...
1172 //-----------------------------------------------------------------------------
1173 t_CKINT Chuck_Array16::back( t_CKCOMPLEX * val ) const
1175 // check
1176 if( m_vector.size() == 0 )
1177 return 0;
1179 // get
1180 *val = m_vector.back();
1182 return 1;
1188 //-----------------------------------------------------------------------------
1189 // name: clear()
1190 // desc: ...
1191 //-----------------------------------------------------------------------------
1192 void Chuck_Array16::clear( )
1194 // zero
1195 zero( 0, m_vector.size() );
1197 // clear vector
1198 m_vector.clear();
1204 //-----------------------------------------------------------------------------
1205 // name: set_capacity()
1206 // desc: ...
1207 //-----------------------------------------------------------------------------
1208 t_CKINT Chuck_Array16::set_capacity( t_CKINT capacity )
1210 // sanity check
1211 assert( capacity >= 0 );
1213 // if less
1214 if( capacity < m_vector.size() )
1215 set_size( capacity );
1217 // resize vector
1218 m_vector.reserve( capacity );
1220 return m_vector.capacity();
1226 //-----------------------------------------------------------------------------
1227 // name: set_size()
1228 // desc: ...
1229 //-----------------------------------------------------------------------------
1230 t_CKINT Chuck_Array16::set_size( t_CKINT size )
1232 // sanity check
1233 assert( size >= 0 );
1235 // if clearing size
1236 if( size < m_vector.size() )
1238 // zero out section
1239 zero( size, m_vector.size() );
1242 // resize vector
1243 m_vector.resize( size );
1245 return m_vector.size();
1251 //-----------------------------------------------------------------------------
1252 // name: zero()
1253 // desc: ...
1254 //-----------------------------------------------------------------------------
1255 void Chuck_Array16::zero( t_CKUINT start, t_CKUINT end )
1257 // sanity check
1258 assert( start <= m_vector.capacity() && end <= m_vector.capacity() );
1260 for( t_CKUINT i = start; i < end; i++ )
1262 // zero
1263 m_vector[i].re = 0.0;
1264 m_vector[i].im = 0.0;
1271 // static
1272 t_CKUINT Chuck_Event::our_can_wait = 0;
1274 //-----------------------------------------------------------------------------
1275 // name: signal()
1276 // desc: signal a event/condition variable, shreduling the next waiting shred
1277 // (if there is one or more)
1278 //-----------------------------------------------------------------------------
1279 void Chuck_Event::signal()
1281 m_queue_lock.acquire();
1282 if( !m_queue.empty() )
1284 Chuck_VM_Shred * shred = m_queue.front();
1285 m_queue.pop();
1286 m_queue_lock.release();
1287 Chuck_VM_Shreduler * shreduler = shred->vm_ref->shreduler();
1288 shred->event = NULL;
1289 shreduler->remove_blocked( shred );
1290 shreduler->shredule( shred );
1291 // push the current time
1292 t_CKTIME *& sp = (t_CKTIME *&)shred->reg->sp;
1293 push_( sp, shreduler->now_system );
1295 else
1296 m_queue_lock.release();
1302 //-----------------------------------------------------------------------------
1303 // name: remove()
1304 // desc: remove a shred from the event queue.
1305 //-----------------------------------------------------------------------------
1306 t_CKBOOL Chuck_Event::remove( Chuck_VM_Shred * shred )
1308 queue<Chuck_VM_Shred *> temp;
1309 t_CKBOOL removed = FALSE;
1310 m_queue_lock.acquire();
1311 while( !m_queue.empty() )
1313 if( m_queue.front() != shred )
1314 temp.push( m_queue.front() );
1315 else {
1316 shred->event = NULL;
1317 removed = TRUE;
1319 m_queue.pop();
1322 m_queue = temp;
1323 m_queue_lock.release();
1324 return removed;
1330 //-----------------------------------------------------------------------------
1331 // name: queue_broadcast()
1332 // desc: queue the event to broadcast a event/condition variable, by the owner
1333 // of the queue
1334 //-----------------------------------------------------------------------------
1335 void Chuck_Event::queue_broadcast()
1337 // TODO: handle multiple VM
1338 m_queue_lock.acquire();
1339 if( !m_queue.empty() )
1341 Chuck_VM_Shred * shred = m_queue.front();
1342 m_queue_lock.release();
1343 shred->vm_ref->queue_event( this, 1 );
1345 else
1346 m_queue_lock.release();
1353 //-----------------------------------------------------------------------------
1354 // name: broadcast()
1355 // desc: broadcast a event/condition variable, shreduling all waiting shreds
1356 //-----------------------------------------------------------------------------
1357 void Chuck_Event::broadcast()
1359 m_queue_lock.acquire();
1360 while( !m_queue.empty() )
1362 m_queue_lock.release();
1363 this->signal();
1364 m_queue_lock.acquire();
1366 m_queue_lock.release();
1372 //-----------------------------------------------------------------------------
1373 // name: wait()
1374 // desc: cause event/condition variable to block the current shred, putting it
1375 // on its waiting list, and suspennd the shred from the VM.
1376 //-----------------------------------------------------------------------------
1377 void Chuck_Event::wait( Chuck_VM_Shred * shred, Chuck_VM * vm )
1379 EM_log( CK_LOG_FINE, "shred '%d' wait on event '%x'...", shred->xid, (t_CKUINT)this );
1380 // make sure the shred info matches the vm
1381 assert( shred->vm_ref == vm );
1383 Chuck_DL_Return RETURN;
1384 f_mfun canwaitplease = (f_mfun)this->vtable->funcs[our_can_wait]->code->native_func;
1385 canwaitplease( this, NULL, &RETURN, shred ); // TODO: check this is right shred
1386 // RETURN.v_int = 1;
1388 // see if we can wait
1389 if( RETURN.v_int )
1391 // suspend
1392 shred->is_running = FALSE;
1394 // add to waiting list
1395 m_queue_lock.acquire();
1396 m_queue.push( shred );
1397 m_queue_lock.release();
1399 // add event to shred
1400 assert( shred->event == NULL );
1401 shred->event = this;
1403 // add shred to shreduler
1404 vm->shreduler()->add_blocked( shred );
1406 else // can't wait
1408 // push the current time
1409 t_CKTIME *& sp = (t_CKTIME *&)shred->reg->sp;
1410 push_( sp, shred->now );
1417 //-----------------------------------------------------------------------------
1418 // name:
1419 // desc:
1420 //-----------------------------------------------------------------------------
1421 Chuck_IO::Chuck_IO()
1427 //-----------------------------------------------------------------------------
1428 // name:
1429 // desc:
1430 //-----------------------------------------------------------------------------
1431 Chuck_IO::~Chuck_IO()
1437 //-----------------------------------------------------------------------------
1438 // name:
1439 // desc:
1440 //-----------------------------------------------------------------------------
1441 Chuck_IO_File * Chuck_IO::openFile( const string & path, t_CKINT flags )
1443 return NULL;
1449 //-----------------------------------------------------------------------------
1450 // name:
1451 // desc:
1452 //-----------------------------------------------------------------------------
1453 string Chuck_IO::currentDir()
1455 return "";
1461 //-----------------------------------------------------------------------------
1462 // name:
1463 // desc:
1464 //-----------------------------------------------------------------------------
1465 string Chuck_IO::changeDir( const string & to )
1467 return "";
1473 //-----------------------------------------------------------------------------
1474 // name:
1475 // desc:
1476 //-----------------------------------------------------------------------------
1477 t_CKBOOL Chuck_IO::isFile( const string & path )
1479 return FALSE;
1485 //-----------------------------------------------------------------------------
1486 // name:
1487 // desc:
1488 //-----------------------------------------------------------------------------
1489 t_CKBOOL Chuck_IO::isDir( const string & path )
1491 return FALSE;
1497 //-----------------------------------------------------------------------------
1498 // name:
1499 // desc:
1500 //-----------------------------------------------------------------------------
1501 t_CKINT Chuck_IO::getSize( const string & path )
1503 return 0;
1509 //-----------------------------------------------------------------------------
1510 // name:
1511 // desc:
1512 //-----------------------------------------------------------------------------
1513 string Chuck_IO::baseName( const string & path )
1515 return "";
1521 //-----------------------------------------------------------------------------
1522 // name:
1523 // desc:
1524 //-----------------------------------------------------------------------------
1525 void Chuck_IO::getContent( vector<string> & content )
1527 content.clear();
1533 //-----------------------------------------------------------------------------
1534 // name: Chuck_IO_File()
1535 // desc: constructor
1536 //-----------------------------------------------------------------------------
1537 Chuck_IO_File::Chuck_IO_File()
1539 // zero things out
1540 m_ready_flags = 0;
1541 m_flags = 0;
1547 //-----------------------------------------------------------------------------
1548 // name: ~Chuck_IO_File()
1549 // desc: destructor
1550 //-----------------------------------------------------------------------------
1551 Chuck_IO_File::~Chuck_IO_File()
1553 // check it
1554 this->close();
1560 //-----------------------------------------------------------------------------
1561 // name: open
1562 // desc: open file from disk
1563 //-----------------------------------------------------------------------------
1564 t_CKBOOL Chuck_IO_File::open( const string & path, t_CKINT flags )
1566 // close first
1567 this->close();
1569 // log
1570 EM_log( CK_LOG_INFO, "(IO): opening file from disk..." );
1571 EM_pushlog();
1572 EM_log( CK_LOG_INFO, "(IO): path: %s", path.c_str() );
1573 EM_log( CK_LOG_INFO, "(IO): READ: %s WRITE: %s APPEND: %s PLUS: %s",
1574 flags & Chuck_IO::READ ? "Y" : "N", flags & Chuck_IO::WRITE ? "Y" : "N",
1575 flags & Chuck_IO::APPEND ? "Y" : "N", flags & Chuck_IO::TRUNCATE ? "Y" : "N",
1576 flags & Chuck_IO::BINARY ? "Y" : "N" );
1578 // open modes
1579 int nMode = 0;
1581 // construct mode string
1582 stringstream sout;
1583 if( flags & Chuck_IO::READ )
1585 // write it
1586 sout << "r";
1587 // set ready
1588 m_ready_flags |= Chuck_IO::READ;
1589 // set mode
1590 nMode |= ios::in;
1592 if( flags & Chuck_IO::WRITE )
1594 // write it
1595 sout << "w";
1596 // set ready
1597 m_ready_flags |= Chuck_IO::WRITE;
1598 // set mode
1599 nMode |= ios::out;
1601 if( flags & Chuck_IO::APPEND )
1603 // write it
1604 sout << "a";
1605 // set ready
1606 m_ready_flags |= Chuck_IO::WRITE | Chuck_IO::APPEND;
1607 // set mode
1608 nMode |= ios::out | ios::ate;
1610 if( flags & Chuck_IO::TRUNCATE )
1612 // read + write
1613 if( flags ^ Chuck_IO::WRITE || flags & Chuck_IO::APPEND )
1615 // error
1616 EM_error3( "(FileIO): malformed open flag (TRUNCATE)..." );
1617 EM_error3( " note: must be used with WRITE, and without APPEND" );
1618 goto error;
1621 // write it
1622 sout << "w";
1623 // set ready
1624 m_ready_flags |= Chuck_IO::TRUNCATE;
1625 // set mode
1626 nMode |= ios::trunc;
1628 if( flags & Chuck_IO::BINARY )
1630 // add it
1631 m_ready_flags |= Chuck_IO::BINARY;
1634 // sanity check
1635 if( sout.str().length() == 0 )
1637 // error
1638 EM_error3( "(FileIO): malformed open flag (no operation specified)..." );
1639 goto error;
1642 // log
1643 EM_log( CK_LOG_INFO, "(IO): flag: '%s'", sout.str().c_str() );
1645 // windows sucks for being creative in the wrong places
1646 #ifdef __PLATFORM_WIN32__
1647 // if( flags ^ Chuck_IO::TRUNCATE && flags | Chuck_IO::READ ) nMode |= ios::nocreate;
1648 m_io.open( path.c_str(), nMode );
1649 #else
1650 m_io.open( path.c_str(), (_Ios_Openmode)nMode );
1651 #endif
1653 // check for error
1654 if( !m_io.good() )
1656 EM_error3( "(FileIO): cannot open file: '%s'", path.c_str() );
1657 goto error;
1660 // for write
1661 if( good2write() )
1663 // set precision
1664 setprecision( 6 );
1667 // set path
1668 m_path = path;
1669 // set flags
1670 m_flags = flags;
1672 // pop
1673 EM_poplog();
1675 return TRUE;
1677 error:
1679 // pop
1680 EM_poplog();
1682 // reset
1683 m_ready_flags = 0;
1684 // reset
1685 m_path = "";
1687 return FALSE;
1693 //-----------------------------------------------------------------------------
1694 // name: close
1695 // desc: close file
1696 //-----------------------------------------------------------------------------
1697 t_CKBOOL Chuck_IO_File::close()
1699 // check
1700 if( !m_io.good() )
1701 return FALSE;
1703 // log
1704 EM_log( CK_LOG_INFO, "(IO): closing file '%s'...", m_path.c_str() );
1705 // close it
1706 m_io.close();
1707 m_flags = 0;
1708 m_ready_flags = 0;
1709 m_path = "";
1711 return TRUE;
1717 //-----------------------------------------------------------------------------
1718 // name: more()
1719 // desc: is there more to read?
1720 //-----------------------------------------------------------------------------
1721 t_CKBOOL Chuck_IO_File::more()
1723 return !eof();
1729 //-----------------------------------------------------------------------------
1730 // name: eof()
1731 // desc: end of file?
1732 //-----------------------------------------------------------------------------
1733 t_CKBOOL Chuck_IO_File::eof()
1735 // sanity
1736 if( !m_io.good() ) return TRUE;
1737 return !m_io;
1743 //-----------------------------------------------------------------------------
1744 // name: good2read()
1745 // desc: ready to read?
1746 //-----------------------------------------------------------------------------
1747 t_CKBOOL Chuck_IO_File::good2read()
1749 return ( m_io.good() && m_flags & Chuck_IO::READ );
1755 //-----------------------------------------------------------------------------
1756 // name: good2write()
1757 // desc: ready for write?
1758 //-----------------------------------------------------------------------------
1759 t_CKBOOL Chuck_IO_File::good2write()
1761 return ( m_io.good() && m_flags & Chuck_IO::READ );
1767 //-----------------------------------------------------------------------------
1768 // name: readInt()
1769 // desc: read next as (ascii) integer
1770 //-----------------------------------------------------------------------------
1771 t_CKINT Chuck_IO_File::readInt()
1773 // sanity
1774 if( !good2read() ) return 0;
1776 // read int
1777 t_CKINT val = 0;
1778 // TODO: check for EOF?
1779 m_io >> val;
1781 return val;
1787 //-----------------------------------------------------------------------------
1788 // name: readFloat()
1789 // desc: read next as (ascii) floating point value
1790 //-----------------------------------------------------------------------------
1791 t_CKFLOAT Chuck_IO_File::readFloat()
1793 // sanity
1794 if( !good2read() ) return 0;
1796 // read float
1797 t_CKFLOAT val = 0;
1798 // TODO: check for EOF?
1799 m_io >> val;
1801 return 0;
1807 //-----------------------------------------------------------------------------
1808 // name: readString()
1809 // desc: read next as string
1810 //-----------------------------------------------------------------------------
1811 string Chuck_IO_File::readString()
1813 // sanity
1814 if( !good2read() ) return 0;
1816 // read string
1817 string val;
1818 // TODO: check for EOF?
1819 m_io >> val;
1821 return val;
1827 //-----------------------------------------------------------------------------
1828 // name: readLine()
1829 // desc: read line
1830 //-----------------------------------------------------------------------------
1831 string Chuck_IO_File::readLine()
1833 // sanity
1834 if( !good2read() ) return 0;
1836 // read string
1837 string val;
1838 // TODO: check for EOF?
1839 std::getline( m_io, val );
1841 return val;
1847 //-----------------------------------------------------------------------------
1848 // name: writeInt()
1849 // desc: write (ascii) integer
1850 //-----------------------------------------------------------------------------
1851 t_CKBOOL Chuck_IO_File::writeInt( t_CKINT val )
1853 // sanity
1854 if( !good2write() ) return FALSE;
1856 // write it
1857 m_io << val;
1859 return m_io.good();
1865 //-----------------------------------------------------------------------------
1866 // name: writeFloat()
1867 // desc: write (ascii) floating point value
1868 //-----------------------------------------------------------------------------
1869 t_CKBOOL Chuck_IO_File::writeFloat( t_CKFLOAT val )
1871 // sanity
1872 if( !good2write() ) return 0;
1874 // write it
1875 m_io << val;
1877 return m_io.good();
1883 //-----------------------------------------------------------------------------
1884 // name: writeString()
1885 // desc: write string
1886 //-----------------------------------------------------------------------------
1887 t_CKBOOL Chuck_IO_File::writeString( const string & val )
1889 // sanity
1890 if( !good2read() ) return 0;
1892 // write it
1893 m_io << val;
1895 return m_io.good();
1901 //-----------------------------------------------------------------------------
1902 // name: writeLine()
1903 // desc: write line
1904 //-----------------------------------------------------------------------------
1905 t_CKBOOL Chuck_IO_File::writeLine( const string & val )
1907 // sanity
1908 if( !good2read() ) return 0;
1910 // write it
1911 m_io << val << endl;
1913 return m_io.good();
1920 //-----------------------------------------------------------------------------
1921 // name: read32i()
1922 // desc: read next 32 bits, return as int
1923 //-----------------------------------------------------------------------------
1924 t_CKINT Chuck_IO_File::read32i()
1926 return 0;
1932 //-----------------------------------------------------------------------------
1933 // name: read24i()
1934 // desc: read next 24 bits, return as int
1935 //-----------------------------------------------------------------------------
1936 t_CKINT Chuck_IO_File::read24i()
1938 return 0;
1944 //-----------------------------------------------------------------------------
1945 // name: read16i()
1946 // desc: read next 16 bits, return as int
1947 //-----------------------------------------------------------------------------
1948 t_CKINT Chuck_IO_File::read16i()
1950 return 0;
1956 //-----------------------------------------------------------------------------
1957 // name: read8i()
1958 // desc: return next 8 bits, return as int
1959 //-----------------------------------------------------------------------------
1960 t_CKINT Chuck_IO_File::read8i()
1962 return 0;
1968 //-----------------------------------------------------------------------------
1969 // name: read32f()
1970 // desc: return next 32-bits as (binary) single float
1971 //-----------------------------------------------------------------------------
1972 t_CKSINGLE Chuck_IO_File::read32f()
1974 return 0;
1980 //-----------------------------------------------------------------------------
1981 // name: read64f()
1982 // desc: return next 64-bits as (binary) double float
1983 //-----------------------------------------------------------------------------
1984 t_CKDOUBLE Chuck_IO_File::read64f()
1986 return 0;