Generic tree structure on iOS - ios

I am having a problem with generics tree structure in Objective C. I am mainly Java programmer, so I guess I need help from you guys here. On Android I am using this code without a problem:
public class Tree<T> {
private T head;
private ArrayList<Tree<T>> leafs = new ArrayList<Tree<T>>();
private Tree<T> parent = null;
private HashMap<T, Tree<T>> locate = new HashMap<T, Tree<T>>();
public Tree(T head) {
this.head = head;
locate.put(head, this);
}
public void addLeaf(T root, T leaf) {
if (locate.containsKey(root)) {
locate.get(root).addLeaf(leaf);
} else {
addLeaf(root).addLeaf(leaf);
}
}
public Tree<T> addLeaf(T leaf) {
Tree<T> t = new Tree<T>(leaf);
leafs.add(t);
t.parent = this;
t.locate = this.locate;
locate.put(leaf, t);
return t;
}
public Tree<T> setAsParent(T parentRoot) {
Tree<T> t = new Tree<T>(parentRoot);
t.leafs.add(this);
this.parent = t;
t.locate = this.locate;
t.locate.put(head, this);
t.locate.put(parentRoot, t);
return t;
}
public T getHead() {
return head;
}
public Tree<T> getTree(T element) {
return locate.get(element);
}
public Tree<T> getParent() {
return parent;
}
public Collection<T> getSuccessors(T root) {
Collection<T> successors = new ArrayList<T>();
Tree<T> tree = getTree(root);
if (null != tree) {
for (Tree<T> leaf : tree.leafs) {
successors.add(leaf.head);
}
}
return successors;
}
public Collection<Tree<T>> getSubTrees() {
return leafs;
}
public static <T> Collection<T> getSuccessors(T of, Collection<Tree<T>> in) {
for (Tree<T> tree : in) {
if (tree.locate.containsKey(of)) {
return tree.getSuccessors(of);
}
}
return new ArrayList<T>();
}
}
But when I tried to port it as it is to Objective-C it simply doesn't work. Here is the code:
#implementation Tree {
Node* head;
NSMutableArray* leafs;
Tree* parent;
NSMutableDictionary* locate;
}
#synthesize head;
-(id) initWithHead:(Node *) Head {
self = [super init];
if (self) {
head = Head;
leafs = [[NSMutableArray alloc]init];
locate = [[NSMutableDictionary alloc] init];
[locate setObject:head forKey:(id)self];
}
return self;
}
-(void) addLeafWithRoot:(Node *)Root leaf:(Node *)Leaf {
if([locate objectForKey:Root] != nil) {
[[locate objectForKey:Root] addLeaf:Leaf];
}else{
[[self addLeaf:Root] addLeaf:Leaf];
}
}
-(Tree *) addLeaf:(Node*) Leaf {
Tree * t = [[Tree alloc] initWithHead:Leaf];
[leafs addObject:t];
[t setParent:t];
[self setLocate:[t getLocate]];
[locate setObject:Leaf forKey:(id)t];
return t;
}
-(Tree*) getTree:(Node *) Node {
return [locate objectForKey:Node];
}
-(NSMutableArray *) getSuccesor:(Node *) root {
NSMutableArray *successors = [[NSMutableArray alloc] init];
Tree* tree = [self getTree:root];
if(tree != nil) {
for (Tree* leaf in [tree getLeafs]) {
[successors addObject:[leaf getHead]];
}
}
return successors;
}
-(void) setParent:(Tree *) Tree {
parent = Tree;
}
-(void) setLocate:(NSMutableDictionary *) Locate {
locate = Locate;
}
-(NSMutableDictionary *) getLocate {
return locate;
}
-(NSMutableArray *) getLeafs {
return leafs;
}
-(Node *) getHead {
return head;
}
-(id)copyWithZone:(NSZone *)zone
{
Tree *another = [[[self class] allocWithZone:zone] init];
another.head = self.head;
return another;
}
#end
I guess that is due to, that on Android I am using Tree class Node type and that's simply I cannot use in Objective-C. Can I modify this solution, to works on iOS, or do I have to come with something totally different? Thanks in advance.
By the way, Node class is basic class with getters and setters to hold some text and int information.

There are memory management issues with your implementation. (Head is not retained in init, and you haven't implemented dealloc.) It also has few of the benefits of a tree because it isn't smart about where to put new nodes, and has no facility for searching.
Instead of writing your own basic data type, you should use either CFTree or a Cocoa wrapper for CFTree. See this answer for more.

Related

is there a way to use dependencies injection using typescript

i'm relative new to this, so i want to implement dependency injection using typescript (is the first time I use this pattern), I'm more that using language programming like java or c# for OOP, so there is more easy to apply this pattern,
I found an example on internet and I can use it without problems on eclipse and visual studio, but when i use it on typescript the IDE raise an error like this:
Supplied parameters do not match any signature of call target
and is just at the end of implement it when this error appears
my base class:
class Motor {
Acelerar(): void {
}
GetRevoluciones(): number {
let currentRPM: number = 0;
return currentRPM;
}
}
export {Motor};
my class that uses motor
import { Motor } from "./1";
class Vehiculo {
private m: Motor;
public Vehiculo(motorVehiculo: Motor) {
this.m = motorVehiculo;
}
public GetRevolucionesMotor(): number {
if (this.m != null) {
return this.m.GetRevoluciones();
}
else {
return -1;
}
}
}
export { Vehiculo };
my interface and the type of motor
interface IMotor {
Acelerar(): void;
GetRevoluciones(): number;
}
class MotorGasoline implements IMotor {
private DoAdmission() { }
private DoCompression() { }
private DoExplosion() { }
private DoEscape() { }
Acelerar() {
this.DoAdmission();
this.DoCompression();
this.DoExplosion();
this.DoEscape();
}
GetRevoluciones() {
let currentRPM: number = 0;
return currentRPM;
}
}
class MotorDiesel implements IMotor {
Acelerar() {
this.DoAdmission();
this.DoCompression();
this.DoCombustion();
this.DoEscape();
}
GetRevoluciones() {
let currentRPM: number = 0;
return currentRPM;
}
DoAdmission() { }
DoCompression() { }
DoCombustion() { }
DoEscape() { }
}
and here is where the error appears:
import { Vehiculo } from "./2";
enum TypeMotor {
MOTOR_GASOLINE = 0,
MOTOR_DIESEL = 1
}
class VehiculoFactory {
public static VehiculoCreate(tipo: TypeMotor) {
let v: Vehiculo = null;
switch (tipo) {
case TypeMotor.MOTOR_DIESEL:
v = new Vehiculo(new MotorDiesel()); break;
case TypeMotor.MOTOR_GASOLINE:
v = new Vehiculo(new MotorGasoline()); break;
default: break;
}
return v;
}
}
I don't wanna use any library or module like SIMPLE-DIJS or D4js or any other for the moment, I just wanna know how to implement without them
You have this error because you don't specify a constructor on the Vehiculo type.
To declare a constructor you should use use the constructor keyword and not the name of the class.
class Vehiculo {
private m: Motor;
constructor(motorVehiculo: Motor) {
this.m = motorVehiculo;
}
public GetRevolucionesMotor(): number {
if (this.m != null) {
return this.m.GetRevoluciones();
}
else {
return -1;
}
}
}

How to Create the Custom create function in cocos2d-x

I want to change Create function
for avoiding the Global variable usage.
I want to pass my values (e.g scores) while Calling
and creating other scenes. One method i found is
the use of Global variable in create Function
but i want to use those values without using global
variables. Please reply me fast , i'm new in cocos2d-x.
and also tell me if there is any other method.
i personally use these two approaches ... so choose which fits you the most!
take for example this ScoreScene class and how its created.
1)- approach one
class ScoreScene : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene(bool won, int score) {
auto scene = Scene::create();
auto layer = ScoreScene::create(won, score);
scene->addChild(layer);
return scene;
}
static ScoreScene* create(bool won, int score) {
ScoreScene *layer = new(std::nothrow) ScoreScene;
if (layer)
{
layer->isWinner = won;
layer->m_score = score;
if (layer->init())
{
layer->autorelease();
return layer;
}
}
CC_SAFE_DELETE(layer);
return nullptr;
}
bool init() override {
if(!layer->init()) return;
// initialization code here
return true;
}
private:
// your properties
int m_score;
bool isWinner;
};
1)- approach two (personally preferred)
make just one method which is createScene instead of two.
class ScoreScene : public cocos2d::Layer
{
public:
cocos2d::Scene* ScoreScene::createScene(bool won, int score)
{
ScoreScene *layer = new(std::nothrow) ScoreScene;
if (layer)
{
layer->isWinner = won;
layer->m_score = score;
if (layer->init())
{
auto scene = Scene::create();
layer->autorelease();
scene->addChild(layer);
return scene;
}
}
CC_SAFE_DELETE(layer);
return nullptr;
}
bool init() override {
if(!layer->init()) return;
// initialization code here
return true;
}
private:
// your properties
int m_score;
bool isWinner;
};
I used the same Approach But thanks for answering..
cocos2d::Scene* GameOverScene::createScene(unsigned int tempscoree)
{
GameOverScene *pRet = new(std::nothrow) GameOverScene();
if (pRet && pRet->init(tempscoree))
{
auto scene = Scene::create();
pRet->autorelease();
scene->addChild(pRet);
return scene;
}
else
{
delete pRet;
pRet = NULL;
return NULL;
}
}
bool GameOverScene::init(unsigned int tempScore)
{
if ( !Layer::init() )
{
return false;
}
//Now i can use tempScore any where in to this init() method.
}

List of Class Objects operation in Dart

Have an issue in the below chunk of code.
class Events
{
// some member variables
}
class SVList
{
String name;
int contentLen;
List<Events> listEvents;
SVList()
{
this.name = "";
this.contentLen = 0;
this.listEvents = new List<Events>();
}
}
class GList
{
List<SVList> listSVList;
GList(int Num)
{
this.listSVList = new List<SvList>(num);
}
}
function f1 ()
{
//array of class objects
GList gList = new GList(num);
}
Not able to find "listEvents" member after GList constructor is called. Am I missing anything here.
Referencing glist.listSVList[index] --> do not find member variable 'listEvents'. Any pointers appreciated.
To elaborate , no member variable with 'glist.listSVList[index].listEvents' is found.
you have a typo here:
this.listSVList = new List<SvList>(num); // <== SVList not SvList
function seems wrong here
function f1 () { ... }
in this case you use function as a return type
another typo:
GList(int Num) // <== Num (uppercase)
{
this.listSVList = new List<SvList>(num); // <== num (lowercase)
}
this code worked:
class Events {
// some member variables
}
class SVList {
String name;
int contentLen;
List<Events> listEvents;
SVList() {
this.name = "";
this.contentLen = 0;
this.listEvents = new List<Events>();
}
}
class GList {
List<SVList> listSVList;
GList(int num) {
this.listSVList = new List<SVList>(num);
}
}
main() {
//array of class objects
GList gList = new GList(5);
gList.listSVList[0] = new SVList();
gList.listSVList[0].listEvents.add(new Events());
print(gList.listSVList[0].listEvents.length);
}
What editor are you using?
DartEditor showed all errors immediately after I pasted your code.
Lists in Dart can now be stated as
List<Object> array = []

Code equivalent of out or reference parameters in Dart

In Dart, how would I best code the equivalent of an (immutable/value/non-object) out or reference parameter?
For example in C#-ish I might code:
function void example()
{
int result = 0;
if (tryFindResult(anObject, ref result))
processResult(result);
else
processForNoResult();
}
function bool tryFindResult(Object obj, ref int result)
{
if (obj.Contains("what I'm looking for"))
{
result = aValue;
return true;
}
return false;
}
This is not possible in Dart. Support for struct value types, ref or val keywords were discussed on the Dart mailing list just like week. Here is a link to the discussion where you should let your desire be known:
https://groups.google.com/a/dartlang.org/d/topic/misc/iP5TiJMW1F8/discussion
The Dart-way would be:
void example() {
List result = tryFindResult(anObject);
if (result[0]) {
processResult(result[1]);
} else {
processForNoResult();
}
}
List tryFindResult(Object obj) {
if (obj.contains("What I'm looking for")) {
return [true, aValue];
}
return [false, null];
}
you can also use a tuple package like tuple-2.0.0
add tuple: ^2.0.0
to your pubspec.yaml
then any function can return many typed objects like this:
import 'package:tuple/tuple.dart';
Tuple3<int, String, bool?>? returnMany() {
return ok ? Tuple3(5, "OK", null) : null;
}
var str = returnMany().item2;
In your case:
void example() {
var result = tryFindResult(anObject);
if (result.item1) {
processResult(result.item2!);
} else {
processForNoResult();
}
}
Tuple2<bool, int?> tryFindResult(Object obj) {
if (obj.contains("What I'm looking for")) {
return Tuple2(true, aValue);
}
return Tuple2(false, null);
}
you can throw an exception too when no result.
void example() {
var result = tryFindResult(anObject);
try {
processResult(result);
} on NullException catch(e){
processForNoResult();
}
}
int tryFindResult(Object obj) { // throws NullException
if (obj.contains("What I'm looking for")) {
return aValue;
}
throw NullException();
}

foreach statement overload in d programing language

Hello I would like to define my own class collection, and make it iterable in a foreach statement, just like this :
public class Collection(Type)
{
...
private T head;
private Collection!(T) queue;
}
Collection!(int) temp;
foreach (int t; temp) { ... }
What methods should I define, and how ?
you can specify the front, popfront() and empty functions: (but this will consume your collection unless you use save())
public class Collection(T) { ... private T head; private Collection!(T) queue;
#property T front(){
return head;
}
#property bool empty(){
return queue is null;
}
void popfront(){
head = queue.head;
queue = queue.queue;
}
Collection!T save(){
return new Collection!T(head,queue);
}
}
or use a dedicated struct for iteration (as is done in the std.container module
public class Collection(T) { ... private T head; private Collection!(T) queue;
Range opSlice(){
return Range(head,queue);
}
struct Range{
T h;
Collection!(T) q;
this(T he, Collection!(T) qu){
h=he;
q=qu;
}
#property T front(){
return h;
}
#property bool empty(){
return q is null;
}
void popfront(){
h = q.head;
q= q.queue;
}
Collection!T save(){
return this;
}
}
}
so iteration is done like so
Collection!(int) temp; foreach (int t;temp[]) { ... }
you also can add an opApply for the normal foreach:
public int opApply(int delegate(ref T) dg){
int res=0;
foreach(ref T;this[]){
res = dg(t);
if(res)return res;
}
return res;
}
Take a look at this documentation on ForeachStatements and scroll down a bit.
If I'm reading your example correctly, you could define an opApply for Collection as follows:
public int opApply(int delegate(ref T) dg){
Collection!T p = this;
int res = 0;
while(!res && p !is null){
res = dg(p.head);
p = p.queue;
}
return res;
}
Your Collection class should implement opApply. Your foreach body becomes a delegate to an internal for loop, and you iterate over your internal collection (in your case a queue) using a for loop.
Consider the example given in the docs
class Foo {
uint array[2];
int opApply(int delegate(ref uint) dg)
{ int result = 0;
for (int i = 0; i < array.length; i++)
{
result = dg(array[i]);
if (result)
break;
}
return result;
}
}

Resources