Skip to content
This repository has been archived by the owner on Sep 6, 2024. It is now read-only.

Better introductory documentation #41

Open
helenarobotics opened this issue Oct 25, 2015 · 8 comments
Open

Better introductory documentation #41

helenarobotics opened this issue Oct 25, 2015 · 8 comments

Comments

@helenarobotics
Copy link

I've seen the video, but it assumes that the user will be using the same directory structure/package
org.usfirst.ftc.exampleteam.yourcodehere

We have multiple teams, and since we can, it would be nice if we could use multiple packages to separate out each teams code. However, attempts to create a new structure fail to compile.

@OnRobotRunning
public static void playSoundOnRobotRunning(Context context) {
    SwerveUtil.playSound(context, R.raw.nxtstartup);
}

with

Error:(55, 40) error: cannot find symbol variable raw

(I could find no reference to 'raw' anywhere in the entire project using 'git grep raw').

Second, the documentation at the top of the file 'MyRobotControllerAdministration' contains references to cloning and such, but it's not obvious what changes would need to be made as a team who cloned the repository recently. Are those instructions still relevant? Also, is the name of the class or package name important, or can the class be renamed (there is no inheritance or interface definitions on the class to infer behavior, so it's not obvious how the library is determining how the methods are to be called).

@rgatkinson
Copy link

Thanks for writing!

The 'raw' comes from the name of the directory in which the sound files are found. For YourCodeHere, that's (e.g.) ...\YourCodeHere\src\main\res\raw\nxtstartup.wav. If you're making a parallel module of YourCodeHere, you'll want to copy the sounds in here as well to the corresponding location in your new module. You can use your own sounds, too, if you wish, by putting new / different files in that location.

The name of the class MyRobotControllerAdministration and the package in which it is found are not significant: the methods to be called are found by examining every public static method in every class in the app, looking for ones that have the relevant annotations.

I agree that the documentation is a little stale here; we'll update that.

Thanks again!

@helenarobotics
Copy link
Author

I've got a parallel build structure, but the build can't resolve the class 'R', or if it's resolving it, it doesn't know what R.raw is.

The resources exist in the same location as before, I've just moved things into a different package structure, but in the same 'YourcodeHere' project.

swerve_ftc/YourCodeHere/src/main/java/org/helenarobotics/ftc/team4309/RobotRegistration.java

On a different topic:

The name of the class MyRobotControllerAdministration and the package in which it is found are not significant: the methods to be called are found by examining every public static method in every class in the app, looking for ones that have the relevant annotations.

Wow, isn't that an expensive operation?

@rgatkinson
Copy link

Is there somewhere I could take a look at your code? A git that I could clone would be most convenient.

Yes, in computer terms it's expensive, but not in human terms. And we only ever do it once, when the robot controller app starts up. It's not actually noticeable.

@helenarobotics
Copy link
Author

Sure, I've just uploaded my version of your cloned repo. The file in question is:

https://github.com/helenarobotics/swerve_ftc_app/blob/team4309/YourCodeHere/src/main/java/org/helenarobotics/ftc/team4309/RobotRegistration.java

Re: expensive, scanning the entire classpath is crazy expensive. Both the Spring and Guice folks avoid doing it due to expense. Both frameworks require you to either specify the classes and/or package being scanned due to expense of reflection on every class. It gets even more expensive when additional libraries and frameworks are brought in. (For example, we're considering bringing in the OpenCV classes, which would potentially be scanned for annotations that will never be used).

In a past life, I wrote an ORM library that made heavy use of reflection, and we also limited the classes we scanned to a limited subset (specific package) to avoid the cost of reflection startup due to significant startup/spinup time. However, hardware is much faster than it used to be, so the costs may be inconsequential now as compared to where they once were. Although even in our environment, the cost of scanning a large number of classes is significant (can adds seconds to the start time of our application when we do deployments), although we have literally hundreds or thousands of classes that make up our application (including dependant classes in jars).

Background: I'm a professional SW developer with > 30 years experience, who has been doing Java programming since before version 1.0 was released, and currently write WebApps in Java in my day job.

@rgatkinson
Copy link

Thanks; I’ll take a look.

Re: “Both frameworks require you to either specify the classes and/or package being scanned”. How do they make you go about doing that? That is, do you make an API call somewhere? ‘Would love to avoid the expense, indeed, but also want the clean separation of library and teams’ code.

            Cheers,
            Bob

@helenarobotics
Copy link
Author

Spring: Two ways

Guice: You create a file that is loaded in your startup file, and that references the files that need to be loaded.

Trying to have something that provides a clean separation of team vs. library code is a fantastic goal. The challenge is to try and leave the library unaware (and not affected) by additions of teams, w/out scanning the entire classpath looking for annotated files.

One possible way is to require teams to stick their classes in a specific package (or sub-package), such as org.usfirst.ftc

So, for our team, we would use org.usfirst.ftc.team4309, and your library would limit the scanning to those classes. However, it's not as flexible as it could be (which your scan-the-entire-classpath solution is).

It's something to think about...

@rgatkinson
Copy link

Helena (can I call you that?),

I took a look at your source code; thanks for posting it.

The one additional change needed was to modify swerve_ftc_app\YourCodeHere\src\main\AndroidManifest.xml to have your package name instead of the default; that is, this:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="org.helenarobotics.ftc.team4309"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <application/>
</manifest>

instead of the default

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="org.usfirst.ftc.exampleteam.yourcodehere"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <application/>
</manifest>

With that one change, the code you pointed me to now compiles.

Thanks for all your input. I'll update the 'how to' documentation in the next couple of days to try make all this more clear.

@helenarobotics
Copy link
Author

Wonderful. Thanks for looking into this, and finding a fix for this. I'm not sure how the package gets written into the Manifest file, so I ended up just hand-editing it as you pointed above.

Thanks again!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants