Generated mojom deserialize code doesn't allow control of construction/allocation |
||
Issue descriptionCode which is generated to use struct traits to deserialize creates an instance of target type with the default constructor and then passes a pointer of it to the ::Read() function of custom struct traits implementation. This causes two problems: * Enforces the target type to have a default constructor and a copy constructor, * Disallows returning an instance of a sub-type of the target type as deserialization result. For example, in mojom::Event/ui::Event struct traits, this makes it impossible to return a ui::KeyEvent or any other sub-types of ui::Event as the result.
,
May 10 2016
It seems a copy constructor is not strictly required. Would you please show me where it is needed?
It does require a default constructor. Please consider the following:
// mojom definition:
struct Foo {
Bar bar; // Bar type is custom typemapped to CustomBar.
};
The generated Foo C++ struct will be something like:
struct Foo {
public:
...
CustomBar bar;
};
If there is no default constructor of Bar, how can we generate a reasonable Foo C++ constructor?
About the Read() interface, when you deserialize a Foo struct, it will pass the |bar| field to the StructTraits<Bar, CustomBar>::Read().
It seems you need another layer of indirection to solve your problem. One way is to typemap Bar to something like scoped_ptr<CustomBar>.
,
May 10 2016
I wonder if we could avoid requiring a default constructor for special cases. A very simple solution could be to introduce another typemap option which causes the bindings to expect a StructTraits<M,T>::Read(Reader, std::unique_ptr<Foo>*) instead of StructTraits<M,T>::Read(Reader, Foo*).
,
May 10 2016
RE comment #3:
In this case, what would a Foo field in another struct look like?
Is it still
// (1)
class SomeStruct {
public:
Foo foo;
};
or you mean
// (2)
class SomeStruct {
public:
std::unique_ptr<Foo> foo;
};
With (1), the deserialization code of SomeStruct needs to deal with assigning a std::unique_ptr<Foo> to Foo.
With (2), it seems the same as directly typemapping to std::unique_ptr<Foo> (as I described at the end of comment #2), right?
Thanks!
,
May 10 2016
RE comment #2: Don't we need to do "*out = result" in Read() function? Wouldn't this need a copy constructor (or operator=)?
,
May 10 2016
Ah, you're right. I missed your last sentence. :)
That seems like a reasonable approach.
moshayedi@ do you think that would be sufficient for your use case? i.e. typemapping to std::unique_ptr<ui::Event> instead of simply ui::Event?
Then your Read would look like:
static bool Read(Event_Reader r, std::unique_ptr<ui::Event>* out) {
}
and you could of course do something like out->reset(new ui::KeyEvent(...))
,
May 10 2016
Unless the type is mutable, of course.
,
May 10 2016
Re comment #6: I think this will be sufficient for our use case.
,
May 10 2016
RE comment #5: Not necessarily. Possibly the user could do: out->set_some_field(blah); out->set_another_field(blah); ...
,
May 26 2016
Do you have any estimate on when this can be resolved? Thanks
,
May 26 2016
Sorry for comment #10. I had slightly misunderstood comment #6 earlier. I think it works for us. I'll update the CL accordingly and then mark this as fixed. Thanks.
,
May 26 2016
Thanks for the update. I am closing this bug as won't fix. Please feel free to reopen or file new bugs if you encounter any issues. |
||
►
Sign in to add a comment |
||
Comment 1 by moshayedi@chromium.org
, May 10 2016