General Category > General Discussion

Struct "inheritance"

(1/1)

lerno:
Taking a page from JAI, why not allow "struct includes":


--- Code: ---type MyData struct {
    const char* name;
    State status;
}

type MyDataExtended struct {
    int32 foo;
    MyData data @(inline);
    ExtendedStatus extendedStatus;
}

MyDataExtended foobar;

// initialize foobar here
...
// Init done

--- End code ---



--- Code: ---printf("Value: %s\n", foobar.name) // Due to the @(inline) attribute.

func void MyData.parse(MyData* data) {
    // ...
}

func void randomizeData(MyData* data) {
  // ...
}

foobar.parse() // valid, equivalent to foobar.data.parse()
randomizeData(foobar) // valid, equivalent to randomizeData(foobar.data)

--- End code ---

All of this is resolved during compile time, so this would not work for example:


--- Code: ---func void funky(void *data) {
   randomizeData(cast<MyData>(data));
}

funky(cast<void>(foobar)); // Will not work as expected.

--- End code ---
However, the code WOULD behave nicely if MyDataExtended did not start with the i32 field...

bas:
I think your proposal would complicate the language and create more corner cases. The only thing gained would be
that instead of a.data.name a developer could use a.name. Right?

lerno:
No, not only, it also allows the programmer to use MyDataExtended with every function that takes a MyData. However, there obviously is a difference, for example – let's say that we have some function foo(MyData *) that wants to take ownership of MyData... Then we obviously have some issues with using MyDataExtended, unless the ordering is such that MyData comes first.

The advantage is that it's possible to do something like inheritance without the inheritance. E.g.:


--- Code: ---type Node struct {
   Vector2 position;
   RenderFunction *renderFunction;
}

func void Node.addChild(Node *this, Node *childNode) {
   ...
}
   
func void Node.render(Node *this, RenderState *state) {
   state->push();
   ... // update render state
   for (... all child nodes behind in z order...) {
       node->render(state);
   }
   this->renderFunction(this, state);
   for (... all child nodes after in z order...) {
       node->render(state);
   }
   state->pop();
}

type SpriteNode struct {
   Node baseNode @(inline)
   Texture *texture;
}

func void SpriteNode.init(SpriteNode *this) {
   this.renderFunction = SpriteRenderFunction;
}

//
...
Node *scene;
SpriteNode *sprite;
...
scene->addChild(sprite);
scene->render(state);


--- End code ---

bas:
struct 'inheritance' in already possible in C by just having the other struct as (first) member.
Also, you can already have object-oriented like features by adding function pointers in a
struct (also in C). Those two cover you example already..

lerno:
I disagree, but it was just a suggestion.

Navigation

[0] Message Index

Go to full version