1818
1919JNIEnv *env;
2020JavaVM *jvm;
21+ int nextId = 1 ;
22+
23+ #define CLASS_DIGITAL_INPUT " net/sourceforge/smallbasic/ioio/DigitalOutput"
24+ #define CLASS_ANALOG_INPUT " net/sourceforge/smallbasic/ioio/AnalogInput"
25+ #define CLASS_IOCLASS 1
26+ #define METHOD_OPEN " open"
27+ #define METHOD_READY " isReady"
28+ #define METHOD_WRITE " write"
2129
2230struct IOClass {
2331 IOClass (): _clazz(nullptr ), _instance(nullptr ) {}
@@ -49,77 +57,111 @@ struct IOClass {
4957 return result;
5058 }
5159
60+ bool checkException () {
61+ auto exc = env->ExceptionOccurred ();
62+ if (exc) {
63+ env->ExceptionDescribe ();
64+ env->ExceptionClear ();
65+ }
66+ return exc;
67+ }
68+
5269 bool invokeIV (const char *name, int value) {
5370 bool result = false ;
5471 if (_instance != nullptr ) {
5572 jmethodID method = env->GetMethodID (_clazz, name, " (I)V" );
5673 if (method != nullptr ) {
5774 env->CallVoidMethod (_instance, method, value);
5875 }
59- auto exc = env->ExceptionOccurred ();
60- if (exc) {
61- env->ExceptionDescribe ();
62- env->ExceptionClear ();
63- } else {
76+ if (!checkException ()) {
6477 result = (method != nullptr );
6578 }
6679 }
6780 return result;
6881 }
6982
83+ int invokeI (const char *name) {
84+ int result = 0 ;
85+ if (_instance != nullptr ) {
86+ jmethodID method = env->GetMethodID (_clazz, name, " ()I" );
87+ if (method != nullptr ) {
88+ result = env->CallIntMethod (_instance, method);
89+ }
90+ checkException ();
91+ }
92+ return result;
93+ }
94+
7095 bool open (int pin) {
71- return invokeIV (" open" , pin);
96+ return invokeIV (METHOD_OPEN, pin);
97+ }
98+
99+ int isReady () {
100+ return invokeI (METHOD_READY);
72101 }
73102
74103 bool write (int value) {
75- return invokeIV (" write " , value);
104+ return invokeIV (METHOD_WRITE , value);
76105 }
77106
78107 private:
79108 jclass _clazz;
80109 jobject _instance;
81110};
82111
83- #define CLS_IOCLASS 1
84112robin_hood::unordered_map<int , IOClass> _classMap;
85- int _nextId = 1 ;
86113
87- static int get_io_class_id (var_s *map) {
114+ static int get_io_class_id (var_s *map, var_s *retval ) {
88115 int result = -1 ;
89116 if (is_map (map)) {
90117 int id = map->v .m .id ;
91118 if (id != -1 && _classMap.find (id) != _classMap.end ()) {
92119 result = id;
93120 }
94121 }
122+ if (result == -1 ) {
123+ error (retval, " IOClass not found" );
124+ }
125+ return result;
126+ }
127+
128+ static int cmd_digital_output_is_ready (var_s *self, int param_count, slib_par_t *params, var_s *retval) {
129+ int result = 0 ;
130+ if (param_count != 0 ) {
131+ error (retval, METHOD_READY, 0 );
132+ } else {
133+ int id = get_io_class_id (self, retval);
134+ if (id != -1 ) {
135+ v_setint (retval, _classMap.at (id).isReady ());
136+ result = 1 ;
137+ }
138+ }
95139 return result;
96140}
97141
98142static int cmd_digital_output_write (var_s *self, int param_count, slib_par_t *params, var_s *retval) {
99143 int result = 0 ;
100- if (param_count == 1 ) {
101- int id = get_io_class_id (self);
144+ if (param_count != 1 ) {
145+ error (retval, METHOD_WRITE, 1 );
146+ } else {
147+ int id = get_io_class_id (self, retval);
102148 if (id != -1 ) {
103149 int value = get_param_int (param_count, params, 0 , 0 );
104150 _classMap.at (id).write (value);
105151 result = 1 ;
106- } else {
107- error (retval, " IOClass not found" );
108152 }
109- } else {
110- error (retval, " Missing value argument" );
111153 }
112154 return result;
113155}
114156
115157static int cmd_openanaloginput (int argc, slib_par_t *params, var_t *retval) {
116158 int result;
117159 int pin = get_param_int (argc, params, 0 , 0 );
118- int id = ++_nextId ;
160+ int id = ++nextId ;
119161 IOClass &input = _classMap[id];
120- if (input.create (" net/sourceforge/smallbasic/ioio/AnalogInput " ) &&
162+ if (input.create (CLASS_ANALOG_INPUT ) &&
121163 input.open (pin)) {
122- map_init_id (retval, id, CLS_IOCLASS );
164+ map_init_id (retval, id, CLASS_IOCLASS );
123165 // v_create_func(retval, "write", cmd_digital_output_write);
124166 result = 1 ;
125167 } else {
@@ -133,12 +175,13 @@ static int cmd_openanaloginput(int argc, slib_par_t *params, var_t *retval) {
133175static int cmd_opendigitaloutput (int argc, slib_par_t *params, var_t *retval) {
134176 int result;
135177 int pin = get_param_int (argc, params, 0 , 0 );
136- int id = ++_nextId ;
178+ int id = ++nextId ;
137179 IOClass &output = _classMap[id];
138- if (output.create (" net/sourceforge/smallbasic/ioio/DigitalOutput " ) &&
180+ if (output.create (CLASS_DIGITAL_INPUT ) &&
139181 output.open (pin)) {
140- map_init_id (retval, id, CLS_IOCLASS);
141- v_create_func (retval, " write" , cmd_digital_output_write);
182+ map_init_id (retval, id, CLASS_IOCLASS);
183+ v_create_callback (retval, METHOD_READY, cmd_digital_output_is_ready);
184+ v_create_callback (retval, METHOD_WRITE, cmd_digital_output_write);
142185 result = 1 ;
143186 } else {
144187 _classMap.erase (id);
@@ -187,7 +230,7 @@ int sblib_init(const char *sourceFile) {
187230SBLIB_API void sblib_free (int cls_id, int id) {
188231 if (id != -1 ) {
189232 switch (cls_id) {
190- case CLS_IOCLASS :
233+ case CLASS_IOCLASS :
191234 _classMap.erase (id);
192235 break ;
193236 }
@@ -200,7 +243,7 @@ void sblib_close(void) {
200243 _classMap.clear ();
201244 }
202245 jvm->DetachCurrentThread ();
203- // hangs
246+ // calling this hangs
204247 // jvm->DestroyJavaVM();
205248 env = nullptr ;
206249 jvm = nullptr ;
0 commit comments