Author Topic: Datablock method inheritance is broken (New: Workaround in topic)  (Read 1433 times)

Code: [Select]
datablock PlayerData(Test1 : PlayerStandardArmor)
{
attribute1 = "hello";
attribute2 = "world";
};

function Test1::method1(%this)
{
echo("hello");
}

function Test1::method2(%this)
{
echo("world");
}

datablock PlayerData(Test2 : Test1)
{
attribute2 = "foo";
};

function Test2::method2(%this)
{
parent::method2(%this);
echo("foo");
}

I ran this code from `config/test.cs` on a Blockland installation with literally no Add-Ons (deleted all files including default in Add-Ons folder, bypassed launcher temporarily to prevent them from coming back), and this is the result.

==>echo(test2.attribute1);
hello
==>echo(test2.attribute2);
foo


Attribute inheritance and overwriting still works fine, however for functions, it doesn't work anymore.

==>test2.method1();
<input> (0): Unknown command method1.
  Object Test2(428) Test2 -> armor -> PlayerData -> ShapeBaseData -> GameBaseData -> SimDataBlock -> SimObject
==>test2.method2();
config/test.cs (24): Unknown command method2.
foo
« Last Edit: June 29, 2013, 09:57:21 AM by Port »

The methods never inherited like that?

I tested it shortly after v21 was released and it worked.

The methods never inherited like that?
I thought they did?

I've created a (slightly hacky) system to replace this, for now: childLayer.cs (163 LOC)
Full function list:

void SimObject::addChildLayer(scope)
Adds a new namespace (x::) to the list of child layers on the object.
If the namespace is already a child layer, it is pushed to the top.

void SimObject::removeChildLayer(scope)
Removes a namespace (x::) from the list of child layers on the object.
If the namespace is not a child layer, no errors occur.

bool SimObject::hasChildLayer(scope)
Checks whether or not the object has the given scope as a child layer.

@any SimObject::callChildLayer(method[, *args:40])
Calls the given method on every child layer consecutively from the top.
Returns the first return value that is not "".

@any SimObject::terminalCallChildLayer(method[, *args:40])
Calls the given method on every child layer consecutively from the top.
Returns the first return value that is not "". The difference to ::callChildLayer,
is that this method stops when it reaches a layer that gives a return value that is not "".

Example:

Code: [Select]
function FirstScope::method1(%this)
{
echo("hello");
}

function FirstScope::method2(%this)
{
echo("world");
}

function SecondScope::method2(%this)
{
echo("foo");
}

==>%object = new Anything();
==>%object.addChildLayer(SecondScope);
==>%object.addChildLayer(FirstScope);
==>%object.callChildLayer(method1);
hello
==>%object.callChildLayer(method2);
world
foo