-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Java: Added access object for vector of struct and vector of tables. #5233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
aardappel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This generally looks great! Some suggestions..
| TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100); | ||
|
|
||
| Test.Vector test4Vector = monster.test4Vector(); | ||
| test_0 = test4Vector.get(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't indexing functions in Java typically called at? Or is get more typical?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get is used most often.
tests/JavaTest.java
Outdated
| TestEq(monster.testarrayoftables(0).name(), "Barney"); | ||
| TestEq(monster.testarrayoftables(1).name(), "Frodo"); | ||
| TestEq(monster.testarrayoftables(2).name(), "Wilma"); | ||
| TestEq(monster.testarrayoftablesVector().get(0).name(), "Barney"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe get the vector just once, to not promote people to copy this style? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed :-)
tests/MyGame/Example/Stat.java
Outdated
|
|
||
| public Stat get(int j) { return get(new Stat(), j); } | ||
| public Stat get(Stat obj, int j) { return obj.__assign(__indirect(vector_data_pos + j * vector_element_size, bb), bb); } | ||
| public int length() { return bb.getInt(vector_start_pos);} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while we're caching, could cache the length as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
| /** | ||
| * All vector of tables in the generated code derive from this class, and add their own accessors. | ||
| */ | ||
| public class TableVector { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There doesn't appear anything specific to tables in this class, it could easily work for a vector of doubles or whatever too. Why not add support for vectors of other types while we're at it? I'd think that the gain of only looking up the vector just once is most pronounced with iterating a scalar vector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a number of conceptual issues. The current API for scalar and string vectors is different from the API for structure and table vectors in access objects:
- All of these types are built-in and we need to manually create a vector object for each type of scalar (integer, fractional, byte, etc.) in com.google.flatbuffers, but not in the generated code.
- The generator must add mutability methods to access objects for scalar type vectors if the corresponding flag is set. This conflicts with clause 1. The vectors of tables and structures are immutable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or we will have to generate code for the com.google.flatbuffers package along with the code from the schema. This will be similar to the work of the C ++ compiler with templates. The file structure of the generated code will look something like this:
foo/bar/ - classes from schema
com/google/flatbuffers/ - classes for vectors of built-in types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aardappel The method with the generated classes will be conflicted when several schemes are used in the same project with different values of the --gen-mutable flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this problem solved in C ++ code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's what I am saying: the current TableVector could actually work for other types, and would not need a copy per type.
It be fine to leave out the mutation functions for this particular class if it makes things complicated, since if someone wants to mutate, they can still use the existing functions.
Generally it be nicer to not add copies of such classes to generated code whenever possible (efficiency wise).
In C++, the Vector template always has mutation function, irrespective of whether any mutation generated code exists.
| code += " return null;\n"; | ||
| code += " }\n"; | ||
| } | ||
| if (lang_.language == IDLOptions::kJava) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to also output code for C#, if you have access to a C# compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, I am not an expert in C # and I am not familiar with the subtleties of a language. First I propose to add an alternative API for Java. For C#, do it separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine, leave it out for now then.
3d995e8 to
3d695f7
Compare
|
@aardappel The work is continued. Previous comments have been fixed where possible. |
3d695f7 to
231ee2a
Compare
aardappel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good, excellent work. Some small issues remaining..
| * @param j The index from which the double value will be read. | ||
| * @return the double value at the given index. | ||
| */ | ||
| public double get(int j) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we need all these copies of these typed classes because Java generics can't deal efficiently with scalars, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, generics will generate unnecessary boxing for scalars.
There is also a problem when working with unsigned types.
Generator logic for converting to unsigned types is implemented in ByteVector, ShortVector and IntVector classes.
| */ | ||
| protected int __indirect(int offset) { | ||
| return offset + bb.getInt(offset); | ||
| return __indirect(offset, bb); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably wasn't reused before because this function gets called so often, and it may affect speed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A static version of the __indirect method has been added to the Table class for use in vectors.
The instance method calls a static method to avoid code duplication.
Leave duplication? JIT can inline static methods to avoid the overhead of a method invocation.
static version of __union also depends on static __indirect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since __indirect is so core to FlatBuffers performance on Java, I'd say leave duplication to be safe, yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
231ee2a to
77208c3
Compare
|
@aardappel PTAL |
5722b7e to
e7df90f
Compare
e7df90f to
fa00a2f
Compare
|
Branch rebased on latest master to pass all build checks =) |
|
@aardappel all done |
|
Thanks, looks good! |
…oogle#5233) * Java: Added access object for vector of struct and vector of tables. * Java: Workarounds removed when accessing the union vector.
This commit resolves #5223