C2 forum

General Category => General Discussion => Topic started by: lerno on June 24, 2018, 12:13:33 AM

Title: Struct "inheritance"
Post by: lerno on June 24, 2018, 12:13:33 AM
Taking a page from JAI, why not allow "struct includes":

Code: [Select]
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


Code: [Select]
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)

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

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

funky(cast<void>(foobar)); // Will not work as expected.
However, the code WOULD behave nicely if MyDataExtended did not start with the i32 field...
Title: Re: Struct "inheritance"
Post by: bas on June 25, 2018, 07:53:02 AM
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?
Title: Re: Struct "inheritance"
Post by: lerno on June 25, 2018, 11:37:45 AM
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: [Select]
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);

Title: Re: Struct "inheritance"
Post by: bas on June 27, 2018, 08:57:23 AM
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..
Title: Re: Struct "inheritance"
Post by: lerno on June 28, 2018, 07:18:29 PM
I disagree, but it was just a suggestion.