Skip to content

Commit 4a40624

Browse files
authored
Version - v2.2.2 (#41)
* Get component metadata no matter the circumstance * Fixes related to the previous build 84b0a512 * Fixes related to the previous build cb4788e * Extend "Null Safety" to all metadata functions 30c1dfd9 * Finishing touches * Fix events not handling properly Also removes `ComponentCreated` and is more specific about what ID must be unique. * Overwrite with 1570d2b * Remove ComponentCreated event reference Transferred with 1570d2b * Bump version * Add snippet from ab1eff2 Is more specific about what ID is not unique.
1 parent 5c0616a commit 4a40624

File tree

1 file changed

+89
-45
lines changed

1 file changed

+89
-45
lines changed

src/com/yusufcihan/DynamicComponents/DynamicComponents.java

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
helpUrl = "https://github.com/ysfchn/DynamicComponents-AI2/blob/main/README.md",
4747
iconName = "aiwebres/icon.png",
4848
nonVisible = true,
49-
version = 8,
50-
versionName = "2.2.1"
49+
version = 9,
50+
versionName = "2.2.2"
5151
)
5252
@SimpleObject(external = true)
5353
public class DynamicComponents extends AndroidNonvisibleComponent {
@@ -58,10 +58,10 @@ public class DynamicComponents extends AndroidNonvisibleComponent {
5858
private boolean postOnUiThread = false;
5959

6060
// Components created with Dynamic Components
61-
private final HashMap<String, Component> COMPONENTS = new HashMap<String, Component>();
61+
private final HashMap<String, Component> COMPONENTS = new HashMap<String, Component>();
6262

6363
// IDs of components created with Dynamic Components
64-
private final HashMap<Component, String> COMPONENT_IDS = new HashMap<Component, String>();
64+
private final HashMap<Component, String> COMPONENT_IDS = new HashMap<Component, String>();
6565

6666
private Object lastUsedId = "";
6767
private ArrayList<ComponentListener> componentListeners = new ArrayList<ComponentListener>();
@@ -84,11 +84,11 @@ public boolean exists(Component component) {
8484
public boolean exists(String id) {
8585
return COMPONENTS.containsKey(id);
8686
}
87-
87+
8888
public String getClassName(Object componentName) {
8989
String regex = "[^.$@a-zA-Z0-9]";
9090
String componentNameString = componentName.toString().replaceAll(regex, "");
91-
91+
9292
if (componentName instanceof String && componentNameString.contains(".")) {
9393
return componentNameString;
9494
} else if (componentName instanceof String) {
@@ -120,7 +120,7 @@ public void newInstance(Constructor<?> constructor, String id, AndroidViewCompon
120120
} catch(Exception e) {
121121
throw new YailRuntimeError(e.getMessage(), "DynamicComponents");
122122
} finally {
123-
if (mComponent != null) {
123+
if (!isEmptyOrNull(mComponent)) {
124124
String mComponentClassName = mComponent.getClass().getSimpleName();
125125
if (mComponentClassName == "ImageSprite" || mComponentClassName == "Sprite") {
126126
Invoke(mComponent, "Initialize", new YailList());
@@ -158,6 +158,16 @@ public void notifyListenersOfCreation(Component component, String id) {
158158
}
159159
}
160160

161+
public boolean isEmptyOrNull(Object item) {
162+
if (item instanceof String) {
163+
String mItem = item.toString();
164+
mItem = mItem.replace(" ", "");
165+
return mItem.isEmpty();
166+
}
167+
168+
return item == null;
169+
}
170+
161171
@DesignerProperty(
162172
defaultValue = "UI",
163173
editorArgs = {"Main", "UI"},
@@ -167,21 +177,25 @@ public void notifyListenersOfCreation(Component component, String id) {
167177
public void Thread(String thread) {
168178
postOnUiThread = (thread == "UI");
169179
}
170-
171-
@Deprecated
172-
@SimpleEvent(description = "Do NOT use this event. Use 'ComponentBuilt' as a replacement.")
173-
public void ComponentCreated(String id, String type) {
174-
EventDispatcher.dispatchEvent(this, "ComponentCreated", id, type);
175-
}
176180

177181
@SimpleEvent(description = "Is called after a component has been created.")
178-
public void ComponentBuilt(Component component, String id, String type) {
179-
EventDispatcher.dispatchEvent(this, "ComponentBuilt", component, id, type);
182+
public void ComponentBuilt(final Component component, final String id, final String type) {
183+
new Handler(Looper.getMainLooper()).post(new Runnable() {
184+
@Override
185+
public void run() {
186+
EventDispatcher.dispatchEvent(DynamicComponents.this, "ComponentBuilt", component, id, type);
187+
}
188+
});
180189
}
181190

182191
@SimpleEvent(description = "Is called after a schema has/mostly finished component creation.")
183-
public void SchemaCreated(String name, YailList parameters) {
184-
EventDispatcher.dispatchEvent(this, "SchemaCreated", name, parameters);
192+
public void SchemaCreated(final String name, final YailList parameters) {
193+
new Handler(Looper.getMainLooper()).post(new Runnable() {
194+
@Override
195+
public void run() {
196+
EventDispatcher.dispatchEvent(DynamicComponents.this, "SchemaCreated", name, parameters);
197+
}
198+
});
185199
}
186200

187201
@SimpleFunction(description = "Assign a new ID to a previously created dynamic component.")
@@ -220,10 +234,8 @@ public void run() {
220234
} else {
221235
UTIL_INSTANCE.newInstance(mConstructor, id, in);
222236
}
223-
224-
ComponentCreated(id.toString(), mClass.getSimpleName());
225237
} else {
226-
throw new YailRuntimeError("ID must be unique.", "DynamicComponents");
238+
throw new YailRuntimeError("Expected a unique ID, got '" + id + "'.", "DynamicComponents");
227239
}
228240
}
229241

@@ -247,10 +259,14 @@ public Object GetComponent(String id) {
247259
public YailDictionary GetComponentMeta(Component component) {
248260
Class<?> mClass = component.getClass();
249261
DesignerComponent mDesignerAnnotation = mClass.getAnnotation(DesignerComponent.class);
262+
boolean mHasDesigner = !isEmptyOrNull(mDesignerAnnotation);
263+
boolean mHasObject = false;
250264
SimpleObject mObjectAnnotation = mClass.getAnnotation(SimpleObject.class);
251265
YailDictionary mMeta = new YailDictionary();
266+
mHasObject = !isEmptyOrNull(mObjectAnnotation);
252267

253-
if (mDesignerAnnotation != null) {
268+
if (mHasDesigner && mHasObject) {
269+
// Return all metadata
254270
mMeta.put("androidMinSdk", mDesignerAnnotation.androidMinSdk());
255271
mMeta.put("category", mDesignerAnnotation.category());
256272
mMeta.put("dateBuilt", mDesignerAnnotation.dateBuilt());
@@ -265,6 +281,17 @@ public YailDictionary GetComponentMeta(Component component) {
265281
mMeta.put("type", mClass.getSimpleName());
266282
mMeta.put("version", mDesignerAnnotation.version());
267283
mMeta.put("versionName", mDesignerAnnotation.versionName());
284+
} else if (!mHasDesigner && mHasObject) {
285+
// Return some amount of metadata even if there is no
286+
// @DesignerComponent annotation provided
287+
mMeta.put("external", mObjectAnnotation.external());
288+
mMeta.put("package", mClass.getName());
289+
mMeta.put("type", mClass.getSimpleName());
290+
} else {
291+
// Return the least amount of metadata if no
292+
// annotation is provided
293+
mMeta.put("package", mClass.getName());
294+
mMeta.put("type", mClass.getSimpleName());
268295
}
269296

270297
return mMeta;
@@ -277,15 +304,22 @@ public YailDictionary GetEventMeta(Component component) {
277304

278305
for (Method mMethod : mMethods) {
279306
SimpleEvent mAnnotation = mMethod.getAnnotation(SimpleEvent.class);
307+
boolean mIsDeprecated = !isEmptyOrNull(mMethod.getAnnotation(Deprecated.class));
280308
String mName = mMethod.getName();
281309
YailDictionary mEventMeta = new YailDictionary();
282310

283-
if (mAnnotation != null) {
311+
if (!isEmptyOrNull(mAnnotation)) {
312+
// Return all metadata
284313
mEventMeta.put("description", mAnnotation.description());
285-
mEventMeta.put("isDeprecated", (mMethod.getAnnotation(Deprecated.class) != null));
314+
mEventMeta.put("isDeprecated", mIsDeprecated);
286315
mEventMeta.put("userVisible", mAnnotation.userVisible());
287-
mEvents.put(mName, mEventMeta);
316+
} else {
317+
// Return the least amount of metadata if no
318+
// annotation is provided
319+
mEventMeta.put("isDeprecated", mIsDeprecated);
288320
}
321+
322+
mEvents.put(mName, mEventMeta);
289323
}
290324

291325
return mEvents;
@@ -298,23 +332,30 @@ public YailDictionary GetFunctionMeta(Component component) {
298332

299333
for (Method mMethod : mMethods) {
300334
SimpleFunction mAnnotation = mMethod.getAnnotation(SimpleFunction.class);
335+
boolean mIsDeprecated = !isEmptyOrNull(mMethod.getAnnotation(Deprecated.class));
301336
String mName = mMethod.getName();
302337
YailDictionary mFunctionMeta = new YailDictionary();
303338

304-
if (mAnnotation != null) {
339+
if (!isEmptyOrNull(mAnnotation)) {
340+
// Return all metadata
305341
mFunctionMeta.put("description", mAnnotation.description());
306-
mFunctionMeta.put("isDeprecated", (mMethod.getAnnotation(Deprecated.class) != null));
342+
mFunctionMeta.put("isDeprecated", mIsDeprecated);
307343
mFunctionMeta.put("userVisible", mAnnotation.userVisible());
308-
mFunctions.put(mName, mFunctionMeta);
344+
} else {
345+
// Return the least amount of metadata if no
346+
// annotation is provided
347+
mFunctionMeta.put("isDeprecated", mIsDeprecated);
309348
}
349+
350+
mFunctions.put(mName, mFunctionMeta);
310351
}
311352

312353
return mFunctions;
313354
}
314355

315356
@SimpleFunction(description = "Returns the ID of the specified component.")
316357
public String GetId(Component component) {
317-
if (component != null || COMPONENT_IDS.containsKey(component)) {
358+
if (!isEmptyOrNull(component) || COMPONENT_IDS.containsKey(component)) {
318359
return COMPONENT_IDS.get(component);
319360
}
320361

@@ -331,9 +372,9 @@ public String GetName(Component component) {
331372
public int GetOrder(AndroidViewComponent component) {
332373
View mComponent = (View) component.getView();
333374
int mIndex = 0;
334-
ViewGroup mParent = (mComponent != null ? (ViewGroup) mComponent.getParent() : null);
375+
ViewGroup mParent = (!isEmptyOrNull(mComponent) ? (ViewGroup) mComponent.getParent() : null);
335376

336-
if (mComponent != null && mParent != null) {
377+
if (!isEmptyOrNull(mComponent) && !isEmptyOrNull(mParent)) {
337378
mIndex = mParent.indexOfChild(mComponent) + 1;
338379
}
339380

@@ -352,25 +393,28 @@ public YailDictionary GetPropertyMeta(Component component) {
352393

353394
for (Method mMethod : mMethods) {
354395
DesignerProperty mDesignerAnnotation = mMethod.getAnnotation(DesignerProperty.class);
396+
boolean mHasDesigner = !isEmptyOrNull(mDesignerAnnotation);
397+
boolean mHasProperty = false;
355398
SimpleProperty mPropertyAnnotation = mMethod.getAnnotation(SimpleProperty.class);
356399
String mName = mMethod.getName();
357400
YailDictionary mPropertyMeta = new YailDictionary();
358-
Object mValue = Invoke(component, mName, new YailList());;
401+
Object mValue = Invoke(component, mName, new YailList());
402+
mHasProperty = !isEmptyOrNull(mPropertyAnnotation);
359403

360-
if (mPropertyAnnotation != null) {
404+
if (mHasProperty) {
361405
mPropertyMeta.put("description", mPropertyAnnotation.description());
362406
mPropertyMeta.put("category", mPropertyAnnotation.category());
363407

364-
if (mDesignerAnnotation != null) {
408+
if (mHasDesigner) {
365409
YailDictionary mDesignerMeta = new YailDictionary();
366410
mDesignerMeta.put("defaultValue", mDesignerAnnotation.defaultValue());
367411
mDesignerMeta.put("editorArgs", mDesignerAnnotation.editorArgs());
368412
mDesignerMeta.put("editorType", mDesignerAnnotation.editorType());
369413
mPropertyMeta.put("designer", mDesignerMeta);
370414
}
371415

372-
mPropertyMeta.put("isDeprecated", (mMethod.getAnnotation(Deprecated.class) != null));
373-
mPropertyMeta.put("isDesignerProperty", (mDesignerAnnotation != null));
416+
mPropertyMeta.put("isDeprecated", (!isEmptyOrNull(mMethod.getAnnotation(Deprecated.class))));
417+
mPropertyMeta.put("isDesignerProperty", mHasDesigner);
374418
mPropertyMeta.put("userVisible", mPropertyAnnotation.userVisible());
375419
mPropertyMeta.put("value", mValue);
376420
mProperties.put(mName, mPropertyMeta);
@@ -382,7 +426,7 @@ public YailDictionary GetPropertyMeta(Component component) {
382426

383427
@SimpleFunction(description = "Invokes a method with parameters.")
384428
public Object Invoke(Component component, String name, YailList parameters) {
385-
if (component != null) {
429+
if (!isEmptyOrNull(component)) {
386430
Object mInvokedMethod = null;
387431
Method[] mMethods = component.getClass().getMethods();
388432

@@ -412,7 +456,7 @@ public Object Invoke(Component component, String name, YailList parameters) {
412456
} catch (Exception e) {
413457
throw new YailRuntimeError(e.getMessage(), "DynamicComponents");
414458
} finally {
415-
if (mInvokedMethod != null) {
459+
if (!isEmptyOrNull(mInvokedMethod)) {
416460
return mInvokedMethod;
417461
} else {
418462
return "";
@@ -442,7 +486,7 @@ public String ListDetails(Component component) {
442486
@SimpleFunction(description = "Moves the specified component to the specified view.")
443487
public void Move(AndroidViewComponent arrangement, AndroidViewComponent component) {
444488
View mComponent = (View) component.getView();
445-
ViewGroup mParent = (mComponent != null ? (ViewGroup) mComponent.getParent() : null);
489+
ViewGroup mParent = (!isEmptyOrNull(mComponent) ? (ViewGroup) mComponent.getParent() : null);
446490

447491
mParent.removeView(mComponent);
448492

@@ -462,7 +506,7 @@ public String RandomUUID() {
462506
public void Remove(String id) {
463507
Object component = COMPONENTS.get(id);
464508

465-
if (component != null) {
509+
if (!isEmptyOrNull(component)) {
466510
try {
467511
Method mMethod = component.getClass().getMethod("getView");
468512
final View mComponent = (View) mMethod.invoke(component);
@@ -481,7 +525,7 @@ public void run() {
481525
} catch (Exception e) {
482526
e.printStackTrace();
483527
}
484-
528+
485529
COMPONENTS.remove(id);
486530
COMPONENT_IDS.remove(component);
487531
}
@@ -525,12 +569,12 @@ public void Schema(AndroidViewComponent in, final String template, final YailLis
525569
JSONObject mScheme = new JSONObject(template);
526570
String newTemplate = template;
527571

528-
if (!template.replace(" ", "").isEmpty() && mScheme.has("components")) {
572+
if (!isEmptyOrNull(template) && mScheme.has("components")) {
529573
propertiesArray = new JSONArray();
530574

531575
JSONArray mKeys = (mScheme.has("keys") ? mScheme.getJSONArray("keys") : null);
532576

533-
if (mKeys != null && mKeys.length() == parameters.length() - 1) {
577+
if (!isEmptyOrNull(mKeys) && mKeys.length() == parameters.length() - 1) {
534578
for (int i = 0; i < mKeys.length(); i++) {
535579
String keyPercent = "%" + mKeys.getString(i);
536580
String keyBracket = "{" + mKeys.getString(i) + "}";
@@ -563,8 +607,8 @@ public void onCreation(Component component, String id) {
563607

564608
for (int k = 0; k < keys.length(); k++) {
565609
Invoke(
566-
(Component) GetComponent(mId),
567-
keys.getString(k),
610+
(Component) GetComponent(mId),
611+
keys.getString(k),
568612
YailList.makeList(new Object[] {
569613
mProperties.get(keys.getString(k))
570614
})
@@ -577,7 +621,7 @@ public void onCreation(Component component, String id) {
577621
};
578622

579623
componentListeners.add(listener);
580-
624+
581625
Create(mRoot, mType, mId);
582626
}
583627

0 commit comments

Comments
 (0)