What is *your* opinion about helper blocks in App Inventor? (GSoC Project - User Feedback)

thanks @BeksOmega

when i used your code to make extension i got error -

 [javac] An annotation processor threw an uncaught exception.
    [javac] Consult the following stack trace for details.
    [javac] java.lang.IllegalArgumentException: OptionList Class: com.aktech.test.Animal is not available. Make sure that it is available to the compiler.
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.tryAddOptionList(ComponentProcessor.java:1923)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.optionListToHelperKey(ComponentProcessor.java:1898)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.hasOptionListHelper(ComponentProcessor.java:1865)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.elementToHelperKey(ComponentProcessor.java:1823)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.varElemToParameter(ComponentProcessor.java:2075)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.processMethods(ComponentProcessor.java:2524)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.processComponent(ComponentProcessor.java:1709)
    [javac]     at com.google.appinventor.components.scripts.ComponentProcessor.process(ComponentProcessor.java:1417)
    [javac]     at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
    [javac]     at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
    [javac]     at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
    [javac]     at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
    [javac]     at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
    [javac]     at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
    [javac]     at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
    [javac]     at com.sun.tools.javac.main.Main.compile(Main.java:523)
    [javac]     at com.sun.tools.javac.main.Main.compile(Main.java:381)
    [javac]     at com.sun.tools.javac.main.Main.compile(Main.java:370)
    [javac]     at com.sun.tools.javac.main.Main.compile(Main.java:361)
    [javac]     at com.sun.tools.javac.Main.compile(Main.java:56)
    [javac]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [javac]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    [javac]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [javac]     at java.lang.reflect.Method.invoke(Method.java:498)
    [javac]     at org.apache.tools.ant.taskdefs.compilers.Javac13.execute(Javac13.java:57)
    [javac]     at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:1388)
    [javac]     at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:1117)
    [javac]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    [javac]     at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    [javac]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [javac]     at java.lang.reflect.Method.invoke(Method.java:498)
    [javac]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:99)
    [javac]     at org.apache.tools.ant.Task.perform(Task.java:350)
    [javac]     at java.util.Vector.forEach(Vector.java:1277)
    [javac]     at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:67)
    [javac]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    [javac]     at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    [javac]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [javac]     at java.lang.reflect.Method.invoke(Method.java:498)
    [javac]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:99)
    [javac]     at org.apache.tools.ant.Task.perform(Task.java:350)
    [javac]     at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:391)
    [javac]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    [javac]     at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    [javac]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [javac]     at java.lang.reflect.Method.invoke(Method.java:498)
    [javac]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:99)
    [javac]     at org.apache.tools.ant.Task.perform(Task.java:350)
    [javac]     at org.apache.tools.ant.Target.execute(Target.java:449)
    [javac]     at org.apache.tools.ant.Target.performTasks(Target.java:470)
    [javac]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1401)
    [javac]     at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:36)
    [javac]     at org.apache.tools.ant.Project.executeTargets(Project.java:1264)
    [javac]     at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:437)
    [javac]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    [javac]     at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    [javac]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [javac]     at java.lang.reflect.Method.invoke(Method.java:498)
    [javac]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:99)
    [javac]     at org.apache.tools.ant.Task.perform(Task.java:350)
    [javac]     at org.apache.tools.ant.Target.execute(Target.java:449)
    [javac]     at org.apache.tools.ant.Target.performTasks(Target.java:470)
    [javac]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1401)
    [javac]     at org.apache.tools.ant.Project.executeTarget(Project.java:1374)
    [javac]     at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    [javac]     at org.apache.tools.ant.Project.executeTargets(Project.java:1264)
    [javac]     at org.apache.tools.ant.Main.runBuild(Main.java:827)
    [javac]     at org.apache.tools.ant.Main.startAnt(Main.java:223)
    [javac]     at org.apache.tools.ant.launch.Launcher.run(Launcher.java:284)
    [javac]     at org.apache.tools.ant.launch.Launcher.main(Launcher.java:101)

BUILD FAILED
C:\AppinventorShadowBlock\appinventor-sources-ucr\appinventor\build.xml:46: The following error occurred while executing this line:
C:\AppinventorShadowBlock\appinventor-sources-ucr\appinventor\components\build.xml:217: The following error occurred while executing this line:
C:\AppinventorShadowBlock\appinventor-sources-ucr\appinventor\build-common.xml:125: Compile failed; see the compiler error output for details.

I'm sorry man, I'm quite busy with other projects at the moment and I'm not set up for App Inventor development right now :confused: If you start a new thread with info about what you're doing and that stack trace I'm sure someone more active can help you out =)

Sorry I can't be more help :confused: Best of luck on your project!
--Beka

2 Likes

Do your sources even have the code of her pr ? U will need to manually add it for now as I think it is not yet merged with master

i am using her sources only

As for extensions, the truth is that you will still need to use green blocks for constant values to ensure compatibility with other builders. Unless other constructors also introduce helper blocks.

helpers

After checking in Companion and APK, however, it doesn't work.

helpers

Everything according to the descriptions of @BeksOmega.

Tested on NB187 release test server.

2 Likes

Are you using a companion associated with the test server? Or just the normal one fromt the play store? If I remember right, the new helper blocks require a different companion to work correctly.

Companion with the test server 2.60t5u. But also in the APK it does not work. The second picture is from the APK.
I copied virtually everything from your DOC. I only changed the variable types to int and Integer and the class name to LinkType. Compiles correctly, reports no errors. I also tried to put the helpers folder in different places. The effect is always the same.
I'll try with String again.

It's the same with String. Maybe I have to wait for the official release and extension template.

Hmm. I am not able to get the extension to compile when I try to use a newly introduced type into the language. I'm tracking it down and I'll see what we can do about fixing it.

3 Likes

I managed to compile. Helper blocks are visible but do not return values. Assets blocks work fine.

Hi. Can the helper blocks return boolean values? Because I can't get it.

I don't believe this is the case, but what would be the value beyond using the true/false blocks?

The extension needs a boolean value so I thought it could be added with the helper block. the user could only select the appropriate value without dragging logical built-in blocks.

Hmm. I think this is something we could add, but at the moment only Integer and String are supported types.

Edit: Alternatively, you might be able to do the following:

public enum MyOption implements OptionList<Integer> {
  OptionA(false),
  OptionB(true);

  private final boolean value;

  MyOption(boolean value) {
    this.value = value;
  }

  public boolean toBoolean() {
    return value;
  }

  // implement the standard methods for Helper blocks here
}

And then in your extension:

public class MyExtension {
  @SimpleProperty
  public void MyProperty(MyOption input) {
    this.value = input.toBoolean();
  }
}
1 Like

I didn't realize there is a method that converts to a boolean value. Thanks.

You can also be "C-style" and interpret a 0 as false and 1 as true. Not ideal, but it would work.

So far I have worked with this and it worked fine.:

@Options(Animal.class) String animal

When I use it:

Animal animal

I can't work with a string in extension, e.g .:

if (animal == "elephant") {}

This causes a compile error:

error: incomparable types: Animal and String

1 Like

Assuming that Elephant is an item in the enumeration, you would probably want to do this instead:

if (animal == Animal.Elephant) {}
1 Like

Thanks. I am using a workaround:

if (animal + "" == "elephant") {}

but now I can do it right.

An important thing to note here is that the == operator checks identity, not equality, when it comes to objects, so this if statement using strings is likely to fail. If you want to compare strings, use the .equals method instead:

if ("elephant".equals(animal.toString())) {}
1 Like