Skip to content

Commit 5dfa565

Browse files
committed
refactoring
1 parent 77c9179 commit 5dfa565

4 files changed

Lines changed: 75 additions & 65 deletions

File tree

ioio/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SmallBASIC
2-
# Copyright(C) 2001-2023 Chris Warren-Smith.
2+
# Copyright(C) 2024 Chris Warren-Smith.
33
#
44
# This program is distributed under the terms of the GPL v2.0 or later
55
# Download the GNU Public License (GPL) from www.gnu.org

ioio/main.cpp

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -17,84 +17,91 @@
1717

1818
JNIEnv *env;
1919
JavaVM *jvm;
20-
jclass analogInputClass = nullptr;
21-
jobject analogInput = nullptr;
2220

23-
jclass digitalOutputClass = nullptr;
24-
jobject digitalOutput = nullptr;
21+
struct IOClass {
22+
IOClass(): _clazz(nullptr), _instance(nullptr) {}
2523

26-
jobject createInstance(jclass clazz) {
27-
jobject result = nullptr;
28-
if (clazz == nullptr) {
29-
env->ExceptionDescribe();
30-
} else {
31-
jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V");
32-
if (constructor == nullptr) {
33-
env->ExceptionDescribe();
24+
bool create(const char *path) {
25+
bool result;
26+
if (_instance != nullptr) {
27+
// error: already constructed
28+
result = false;
3429
} else {
35-
result = env->NewObject(clazz, constructor);
30+
_clazz = env->FindClass(path);
31+
if (_clazz == nullptr) {
32+
env->ExceptionDescribe();
33+
} else {
34+
jmethodID constructor = env->GetMethodID(_clazz, "<init>", "()V");
35+
if (constructor == nullptr) {
36+
env->ExceptionDescribe();
37+
} else {
38+
_instance = env->NewObject(_clazz, constructor);
39+
}
40+
}
41+
result = _instance != nullptr;
3642
}
43+
return result;
3744
}
38-
return result;
39-
}
4045

41-
int invokeIV(jclass clazz, jobject instance, const char *name, int value) {
42-
int result = 0;
43-
if (instance != nullptr) {
44-
jmethodID method = env->GetMethodID(clazz, name, "(I)V");
45-
if (method != nullptr) {
46-
env->CallVoidMethod(instance, method, value);
47-
result = 1;
48-
} else {
49-
env->ExceptionDescribe();
46+
bool invoke(const char *name, int value) {
47+
bool result = false;
48+
if (_instance != nullptr) {
49+
jmethodID method = env->GetMethodID(_clazz, name, "(I)V");
50+
if (method != nullptr) {
51+
env->CallVoidMethod(_instance, method, value);
52+
result = true;
53+
} else {
54+
env->ExceptionDescribe();
55+
}
5056
}
57+
return result;
5158
}
52-
return result;
53-
}
5459

55-
int invokeOpen(jclass clazz, jobject instance, int pin) {
56-
return invokeIV(clazz, instance, "open", pin);
57-
}
60+
bool open(int pin) {
61+
return invoke("open", pin);
62+
}
63+
64+
bool write(int value) {
65+
return invoke("write", value);
66+
}
67+
68+
private:
69+
jclass _clazz;
70+
jobject _instance;
71+
};
72+
73+
IOClass analogInput;
74+
IOClass digitalOutput;
5875

5976
static void cmd_digital_output_write(var_s *self, var_s *retval) {
60-
int value = 0;
61-
if (digitalOutput != nullptr && jvm->AttachCurrentThread((void**)&env, nullptr) == JNI_OK) {
62-
invokeIV(digitalOutputClass, digitalOutput, "write", value);
63-
jvm->DetachCurrentThread();
64-
}
77+
static int value = !value;
78+
digitalOutput.write(value);
6579
}
6680

6781
static int cmd_openanaloginput(int argc, slib_par_t *params, var_t *retval) {
82+
int result;
6883
int pin = get_param_int(argc, params, 0, 0);
69-
int result = 0;
70-
if (analogInput == nullptr && jvm->AttachCurrentThread((void**)&env, nullptr) == JNI_OK) {
71-
analogInputClass = env->FindClass("net/sourceforge/smallbasic/ioio/AnalogInput");
72-
analogInput = createInstance(analogInputClass);
73-
result = invokeOpen(analogInputClass, analogInput, pin);
74-
jvm->DetachCurrentThread();
75-
}
76-
if (!result) {
84+
if (analogInput.create("net/sourceforge/smallbasic/ioio/AnalogInput") &&
85+
analogInput.open(pin)) {
86+
result = 1;
87+
} else {
7788
error(retval, "openAnalogInput() failed");
89+
result = 0;
7890
}
7991
return result;
8092
}
8193

8294
static int cmd_opendigitaloutput(int argc, slib_par_t *params, var_t *retval) {
95+
int result;
8396
int pin = get_param_int(argc, params, 0, 0);
84-
int result = 0;
85-
if (digitalOutput == nullptr && jvm->AttachCurrentThread((void**)&env, nullptr) == JNI_OK) {
86-
digitalOutputClass = env->FindClass("net/sourceforge/smallbasic/ioio/DigitalOutput");
87-
digitalOutput = createInstance(digitalOutputClass);
88-
if (digitalOutput != nullptr) {
89-
result = invokeOpen(digitalOutputClass, digitalOutput, pin);
90-
}
91-
jvm->DetachCurrentThread();
92-
}
93-
if (!result) {
94-
error(retval, "openDigitalOutput() failed");
95-
} else {
97+
if (digitalOutput.create("net/sourceforge/smallbasic/ioio/DigitalOutput") &&
98+
digitalOutput.open(pin)) {
9699
map_init(retval);
97100
v_create_func(retval, "write", cmd_digital_output_write);
101+
result = 1;
102+
} else {
103+
error(retval, "openDigitalOutput() failed");
104+
result = 0;
98105
}
99106
return result;
100107
}
@@ -124,17 +131,17 @@ int sblib_init(const char *sourceFile) {
124131
vm_args.nOptions = 2;
125132
vm_args.options = options;
126133
vm_args.ignoreUnrecognized = 0;
127-
int result = (JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args) == JNI_OK);
134+
int result = (JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args) == JNI_OK &&
135+
jvm->AttachCurrentThread((void **)&env, nullptr) == JNI_OK);
128136
if (!result) {
129-
fprintf(stderr, "Unable to create JVM\n");
137+
fprintf(stderr, "Failed to create JVM\n");
130138
}
131139
return result;
132140
}
133141

134142
void sblib_close(void) {
143+
jvm->DetachCurrentThread();
135144
jvm->DestroyJavaVM();
136-
analogInputClass = nullptr;
137-
analogInput = nullptr;
138145
env = nullptr;
139146
jvm = nullptr;
140147
}

ioio/src/main/java/net/sourceforge/smallbasic/ioio/DigitalOutput.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ public IOIOLooper createIOIOLooper(String type, Object extra) {
2323
}
2424

2525
public void open(int pin) {
26-
Log.i(TAG, "openOutput");
26+
Log.i(TAG, "open");
2727
outputLooper = new DigitalOutputLooper(QUEUE, pin);
2828
start();
2929
}
3030

31-
public void setValue(boolean value) {
32-
outputLooper.setValue(value);
31+
public void write(int value) {
32+
System.err.println("WRITE ! write = " + value);
33+
outputLooper.setValue(value == 1);
3334
}
3435
}

ioio/src/test/java/net/sourceforge/smallbasic/ioio/DigitalOutputTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ class DigitalOutputTest {
66
public static void main(String[] args) throws InterruptedException {
77
DigitalOutput output = new DigitalOutput();
88
output.open(IOIO.LED_PIN);
9-
boolean value = true;
9+
System.err.println("done open");
10+
int value = 1;
1011
while (true) {
11-
output.setValue(value);
12-
value = !value;
12+
System.err.println("Setting LED " + value);
13+
output.write(value);
14+
value = value == 1 ? 0 : 1;
1315
Thread.sleep(1000);
1416
}
1517
}

0 commit comments

Comments
 (0)