Nim how to define constructors? - oop

Is there a way in Nim to define constructors for an object?
For example I have
type Deck* = ref object
cards* : array[52, Card]
can I create an empty constructor that creates automatically all the cards?

type
Card = int
Deck* = ref object
cards* : array[52, Card]
proc newDeck: Deck =
new result
for i, c in result.cards.mpairs:
c = i

Related

Lua inheritance and methods

How to inherit a new class player from class actor and make method actor:new(x, y, s) called in method player:new(x, y, s) with the same parameters. I need to make player:new the same but with additional parameters so the player can have more properties than actor.
Is there a way to do this not only in new method, but in other methods, like player:move(x, y) will call actor:move(x, y) or self:move(x, y) but with additional code?
I use this pattern to make classes in modules:
local actor = {}
function actor:new(x, y, s)
self.__index = self
return setmetatable({
posx = x,
posy = y,
sprite = s
}, self)
end
-- methods
return actor
A good way to do this is to have a separate function that initializes your instance. Then you can simply call the base classes initialization within the inherited class.
Like in this example: http://lua-users.org/wiki/ObjectOrientationTutorial
function CreateClass(...)
-- "cls" is the new class
local cls, bases = {}, {...}
-- copy base class contents into the new class
for i, base in ipairs(bases) do
for k, v in pairs(base) do
cls[k] = v
end
end
-- set the class's __index, and start filling an "is_a" table that contains this class and all of its bases
-- so you can do an "instance of" check using my_instance.is_a[MyClass]
cls.__index, cls.is_a = cls, {[cls] = true}
for i, base in ipairs(bases) do
for c in pairs(base.is_a) do
cls.is_a[c] = true
end
cls.is_a[base] = true
end
-- the class's __call metamethod
setmetatable(cls, {__call = function (c, ...)
local instance = setmetatable({}, c)
-- run the init method if it's there
local init = instance._init
if init then init(instance, ...) end
return instance
end})
-- return the new class table, that's ready to fill with methods
return cls
end
You would simply do:
actor = CreateClass()
function actor:_init(x,y,s)
self.posx = x
self.posy = y
self.sprite = s
end
player = CreateClass(actor)
function player:_init(x,y,s,name)
actor.init(self, x,y,s)
self.name = name or "John Doe"
end

extend class default value of parent parameter

I have class B with to parameters x and y extended from class A with parameter x which is optional (all parmaters are non-null) how can I define B in a way that it would be optional and it would use the optional value in constructor of A
val y = 0
val b = if (y == 0) B(y) else B(y, 0)
class B(y: Int, x: Int = 238) : A(x)
open class A(x: Int = 238)
here I have set the default value for x in constructor of B is there any way to achieve this without having to set default value in B
You can achieve this with secondary constructors.
class B : A {
constructor(y: Int): super()
constructor(y: Int, x: Int): super(x)
}
For more information see Kotlin Docs.
Edit:
As #PietroMartinelli mentions the secondary constructors would not work if you need primary constructor. If the derived class has a primary constructor, the base class can (and must) be initialized right there, using the parameters of the primary constructor.
The approach proposed in the #Januson's answer is very nice and clean when you does not neet/would define a primary constructor in the B subclass. If you try to do so, you get compiler errors, because auxiliary constructors must call primary constructor and can't call superclass constructors directly.
If you B subclass need to define a primary constructor, you can approach the problem defining the default value as a constant in A's companion object and use it in both A's and B's primary constructors, as follows:
open class A(val x: Int = DefaultX) {
companion object {
val DefaultX:Int = 238;
}
}
class B(y: Int, x: Int = DefaultX) : A(x)
This way you define the equivalent of a Java static final variable, scoped to A.
You should refer to the superclass' A.DefaultX constant in the B subclass, but you don't need duplicate its value in both class A and class B...
In your situation, something like this maybe help you!
val y = 0
val b = if (y == 0) B(y) else B(y, 0)
class B(y: Int, x: Int) : A() {
constructor(y: Int) : this(y, if (y == 0) 238 else 0)
}
open class A(x: Int = 238)

Check the class of an object from Box2d's user data

I am trying to determine the type of object when detecting collision with Box2d. I want to be able to assign the user data to an object and check to see if its of the correct class type
id object = b->GerUserData():
Then
if([object isKindOfClass:[MyClassObject class]])
However i just get the error "Cannot initialize a variable of type'id' with an rvalue of type 'void*'
Can anyone help me out.
Thanks
Your problem is you are trying to assign an object of type 'id' to a void * type
The method call body->GetUserData(); returns a void pointer. Here it is as defined in the header file of b2Body.h
/// Get the user data pointer that was provided in the body definition.
void* GetUserData() const;
Now, if you are using ARC (Automatic Reference Counting), you need to perform an additional step to cast it back.
id object = (__bridge id) b->GetUserData();
If you are not using ARC, then...
id object = (id) b->GetUserData();
As for checking the type, there are many ways to do this. I personally prefer having an enum called GameObjectType. I can then assign the type in the appropriate constructor of the object. Here is an example of how I do it in my games
for (b2Body * b = world->GetBodyList(); b != NULL; b = b->GetNext()) {
Box2DSprite * sprite = (__bridge Box2DSprite*) b->GetUserData();
id obj = (__bridge id) b->GetUserData();
if (sprite.gameObjectType == kGroundTypeStatic
|| sprite.gameObjectType == kWallType
|| sprite.gameObjectType == kGroundTypeDynamic) {
// Insert Logic here
} // end if
sprite.position = ccp(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
sprite.rotation = CC_RADIANS_TO_DEGREES(b->GetAngle() * -1);
} // end for
Here is how I would go about creating the sprite (Using ARC)
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position = b2Vec2(location.x/PTM_RATIO,
location.y/PTM_RATIO);
// Setting the enum value
self.gameObjectType = kTankType;
self->body = self->world->CreateBody(&bodyDef);
self->body->SetUserData((__bridge void*) self); // Obtain sprite object later
GB2ShapeCache * shapeCache = [GB2ShapeCache sharedShapeCache];
[shapeCache addFixturesToBody:self->body forShapeName:#"Earth_Tank"];
self.anchorPoint = [shapeCache anchorPointForShape:#"Earth_Tank"];
Hope this helps
I'm guessing the error is on this line:
id object = b->GetUserData();
That might be because the return type is void pointer. Try to cast it like that:
id object = (id)b->GetUserData();

Problems allocating arrays when descendant of matlab.mixin.Heterogeneous

Sorry about the formatting, i pasted and then applied the {} control but it still looks mangled. Please educate me if i'm misusing the tool somehow.
I have a base class:
classdef SystemNode < matlab.mixin.Heterogeneous
properties (Abstract)
description
quantity
parent
unit_cost
learning_curve
average_cost
total_cost
children
end
end
I have a descendant:
classdef Subsystem < models.system.SystemNode
properties
description
quantity
parent
children
key
end
properties (Dependent)
unit_cost
learning_curve
average_cost
total_cost
end
methods
function self = Subsystem(description, quantity, parent)
% TODO: Validate Inputs
self.description = description;
self.quantity = quantity;
self.parent = parent;
self.children = [];
self.key = char(java.util.UUID.randomUUID().toString());
end
function add_child(self, node)
% TODO: Validate Inputs
self.children = [self.children node];
end
function unit_cost = get.unit_cost(self)
% Cost if there were only one.
unit_cost = 0;
for child = self.children
unit_cost = child.unit_cost;
end
unit_cost = unit_cost*self.quantity;
end
function learning_curve = get.learning_curve(self)
learning_curve = 0;
end
I can't get .add_child() to work.
for example:
>> ss = models.system.Subsystem('test', 1, []);
>> ss.add_child('a')
>> ss.children
ans =
[]
If i descendend my abstract class from handle instead of the Mixin this works fine. What am i doing wrong??
BTW. I am using Matlab 2011b
Thanks in advance.
It's handle that makes the object behave in a pass-by-reference manner. If you want this kind of behavior, try the following:
classdef SystemNode < matlab.mixin.Heterogeneous & handle
If you do not inherit from handle, you get normal Matlab pass-by-value behavior. In this case, if you want to update the state of an object, you have to return the updated object from the setter method, and store the returned updated value.
So the setter has to return the updated self.
function self = add_child(self, node)
self.children = [self.children node];
end
And calls to it store the returned updated object.
ss = ss.add_child('a')
If you don't store a new value in ss, you're still looking at the value of ss from before the add_child call, with no children.

Objective-C: pointer arithmetic

I need to fill a dae_prim *array_prim; where dae_prim is a class I created.
I want to use C style because I will pass all those data to OpenGL.
When I'm trying to make a : mesh->array_prim[i] = mysexyprim it fails with a "subscript requires size of interface".
I think I understand the problem (Obj-C wants me to use a NSArray) but how can I bypass this?
More code
class meshes:
#public:
dae_prim *prims;
int primcount;
.
model->meshes->prims = malloc(sizeof(dae_prims*) * model->meshes->primcount);
dae_prim *prims = [[dae_prim alloc]init];
model->meshes->prims[1] = prims; //here is the problem
You need to use a double pointer for meshes->prims, as you want an array of pointers.
class meshes:
#public:
dae_prim **prims; /* a C array of objects pointers */
int primcount;
model->meshes->prims = malloc(sizeof(dae_prims*) * model->meshes->primcount);
model->meshes->prims[1] = [[dae_prim alloc]init];
Cheers.