PDA

View Full Version : Several questions


rickh57
10-08-2006, 03:54 PM
Hi:

I'm a software engineer with many years of experience using Java/C++. I'm trying to create a basketball scorekeeping application. My 1st task is to understand the PPL object model. I've created classes for team and player. The team class contains a linked list of players. My problem is that whenever I try traversing the list of players (to find the one with the correct number, compute the score, etc.), it never seems to step through all of the players. I'm not sure when to use references, newobject, etc. I guess that I'm spoiled by Java and PHP5, where everything is a reference! I'm sure that is something simple that I'm doing wrong or not doing... My test code is listed below.

I'm also having problems using the ListBox functions in the Simplified Windows API. Using either ListBox_Add or ListBox_Set seems to succeed (they return true), but the elements that I'm trying to add don't show up. I admit that it has been a very long time since I've done any low level Windows API programming, but am curious about the use of this function. I couldn't find any examples of list box usage in any of the demos.

Finally, just a comment. I've been using PHP and Perl a lot for the last few years and invariably when I create a variable, I put the $ at the beginning of the name not the end. I've been caught by this more times than I'd like to admit! However the error message that is displayed in this case is not very helpful: Invalid character '$' at character position 1586. :|

This is all with PPL 1.04 (Lite version). The Pro trial key that I used when I installed version 1.00 has already expired and until I get a good handle on whether or not I PPL will handle my needs, I'm not yet ready to purchase the Pro or Standard versions.

#class player
Private(number$, score$, fowls$);

nproc create
number$ = args$[0];
score$ = 0;
fowls$ = 0;
end;

public proc addScore(points$)
score$ += points$;
end;

public func getScore
return(score$);
end;

public func getNumber
return(number$);
end;

public func toString
return("Number=" + number$ + ",score=" + score$ + ",fowls=" + fowls$);
end;
#endclass

#class team
Private(players$, numPlayer$);

nproc create
List(players$);
numPlayer$ = 0;
end;

proc destroy
ForEach(players$)
NewObject(p$, "player", players$);
FreeObject(p$);
end;
free(players$);
end;

public proc addPlayer(player$)
NewObject(p$, "player", &player$);
ShowMessage("Player:" + p.toString);
Add(players$, &p$);
end;

public func getScore
ShowMessage("getScore(): Entry");
score$ = 0;
ForEach(players$,&obj$)
NewObject(p$, "player", &obj$);
score$ = p.getScore;
end;
ShowMessage("getScore(): Exit, score=" + score$);
return(score$);
end;

public func getPlayer(number$)
ShowMessage("getPlayer(): Entry, number is " + number$);
retVal$ = 0;
ForEach(players$,&obj$)
NewObject(p$, "player", &obj$);
ShowMessage("player is " + p.toString);
if (p.getNumber == number$)
retVal$ = &p$;
break;
end;
end;
return (retVal$);
end;
#endclass

proc init
Global(homeTeam$);
#object team homeTeam$;
for(i$,0,5)
#object player aPlayer$(i$);
aPlayer.addScore(i$);
homeTeam.addPlayer(&aPlayer$);
end;

// this should add 15 points to player 1's points...
&obj$ = homeTeam.getPlayer(1);
NewObject(p$, "player", &obj$);
p.addScore(15);
end;

PointOfLight
10-09-2006, 01:41 PM
I was messing with rickh57's example a little bit and not having much luck, so I thought I'd create a smaller sample to play with. Here is the code I used:

#class MyClass
private(x$, y$);

nproc create
x$ = 0;
y$ = 0;
end;

proc Destroy
ShowMessage("Buh-Bye");
end;

public proc AssignVals(a$, b$)
x$ = a$;
y$ = b$;
end;

public proc ShowVals(header$)
ShowMessage(header$ + "\nx: " + x$ + ", y$: " + y$);
end;
#endclass

#class WrapClass
public func ClassParamTest(obj$)
MyClass(obj$);
obj.ShowVals("WrapClass");
end;
#endclass

proc ParamTest(obj$)
MyClass(obj$);
obj.ShowVals("ParamTest");
end;

func WinMain()
#object WrapClass wrapTest$;

for(i$, 1, 5)
#object MyClass test$;
test.AssignVals(i$ * 10, i$ * 20);
ParamTest(test$);
wrapTest.ClassParamTest(test$);
FreeObject(test$);
end;
FreeObject(wrapTest$);
end;

The results were rather interesting. I won't detail them here (you can run the code to see them), but the net result is that Except for the first itteration, which did show X$=10, y$=20, the x,y pair never had the results they should have had. In addition, it seems that if you pass an object into a function, that object gets destroyed when the function completes (every time a function exited I got the "Buh-Bye" message). I don't think that's supposed to happen, is it?

PointOfLight
10-09-2006, 02:36 PM
If I comment out the two lines in my WinMain that pass the object to other functions, and just do:

test.ShowVals("WinMain");

in the WinMain function, everything works fine. Is there something special we need to do to pass objects into a function?

kornalius
10-10-2006, 12:08 PM
Hi guys,

PPL uses reference only on objects. &obj$ returns the address of the object. If you pass an object to a proc/func, only its address gets passed over.

We are looking into this code. It looks like there are a few little problems with the object-oriented compiler. We promess a fix for 1.05 due out this week but I will keep you up-to-date.

As for your coding (I understand you are still learning PPL OO) but here is something to simplify your code a lot:

Instead of doing the long and slow code:

NewObject(p$, "player", &player$);

Just do this, to convert the player$ variable to an object:

p$ = player$; // At this point player$ is a reference
player(p$); // convert p$ to an object pointing to player$.

We will also look into the player(player$) issue. It should work but I guess it's not.

PointOfLight
10-10-2006, 01:28 PM
Okay, I know you're already working on OO issues, so this may be moot, but I was playing a bit more with my code. Here's the latest:

#class MyClass
private(x$, y$);

nproc create
x$ = 0;
y$ = 0;
end;

proc Destroy
// ShowMessage("Buh-Bye");
end;

public proc AssignVals(a$, b$)
x$ = a$;
y$ = b$;
end;

public proc ShowVals(header$)
ShowMessage(header$ + "\nx: " + x$ + ", y$: " + y$);
end;
#endclass

#class WrapClass
public func ClassParamTest(obj$)
tmp$ = obj$;
MyClass(tmp$);
tmp.ShowVals("WrapClass");
end;
#endclass

proc ParamTest(obj$)
local(tmp$);
tmp$ = obj$;
MyClass(tmp$);
tmp.ShowVals("ParamTest");
end;

func WinMain()
local(x$, y$);
#object WrapClass wrapTest$;

for(i$, 1, 5)
#object MyClass test$;
x$ = i$ * 10;
y$ = i$ * 20;
test.AssignVals(x$, y$);
test.ShowVals("WinMain");
ParamTest(test$);
wrapTest.ClassParamTest(test$);
FreeObject(test$);
end;
FreeObject(wrapTest$);
end;

This almost works now. What I get is the following:

WinMain
x: 10, y$: 20
ParamTest
x: 10, y$: 20
WrapTest
x: 10, y$: 20

WinMain
x: 10, y$: 20
ParamTest
x: 20, y$: 40
WrapTest
x: 20, y$: 40

and so on. The first WinMain, ParamTest and WrapTest displays are correct. However, the second time around, WinMain should be x: 20, y$: 40. The rest of the values are correct, however.

Also, every time the program exits I get a "Stack too small error!"

kornalius
10-10-2006, 01:48 PM
We found multiple problems with the OO engine. We have fixed quite a few already.

More updates to come on this...

kornalius
10-10-2006, 02:44 PM
Ok, here are the latest:

- Objects are now used as references only. They will need to be manually freed is de-reference. Ex:

#object myclass a$
#object myclass b$
o$ = a$;
a$ = b$; // original a$ object still in memory
freeobject(o$);

- Fixed calling a public proc/func from a class with a variable that has the same name, Ex:

#object player player$
player.ToString;

- Passing objects as parameters (pointer or not) is now fixed.

This code works perfectly in 1.05:

#class player
Private(number$, score$, fowls$);

nproc create
number$ = args$[0];
score$ = 0;
fowls$ = 0;
end;

public proc addScore(points$)
score$ += points$;
end;

public func getScore
return (score$);
end;

public func getNumber
return (number$);
end;

public func toString
return ("Number=" + number$ + ",score=" + score$ + ",fowls=" + fowls$);
end;
#endclass

#class team
Private(players$, numPlayer$);

nproc create
List(players$);
numPlayer$ = 0;
end;

proc destroy
ForEach (players$, obj$)
FreeObject(obj$);
end;
end;

public proc addPlayer(player$)
ShowMessage("Player:" + player.toString);
Add(players$, &player$);
end;

public func getScore
ShowMessage("getScore(): Entry");
score$ = 0;
ForEach (players$, obj$)
NewObject(p$, "player", obj$);
score$ = p.getScore;
end;
ShowMessage("getScore(): Exit, score=" + score$);
return (score$);
end;

public func getPlayer(number$)
ShowMessage("getPlayer(): Entry, number is " + number$);
retVal$ = 0;
ForEach (players$, obj$)
NewObject(p$, "player", obj$);
ShowMessage("player is " + p.toString);
if (p.getNumber == number$)
retVal$ = p$;
break;
end;
end;
return (retVal$);
end;
#endclass

proc main
Global(homeTeam$);
#object team homeTeam$;
for (i$, 0, 5)
#object player aPlayer$(i$);
aPlayer.addScore(i$);
homeTeam.addPlayer(&aPlayer$);
end;

// this should add 15 points to player 1's points...
obj$ = homeTeam.getPlayer(1);
NewObject(p$, "player", obj$);
p.addScore(15);
end;

kornalius
10-10-2006, 02:46 PM
One thing you should look for is that Free(players$) is not valid because the free will try to free only the element it is pointing to, which is an object address in the list.

You don't need to free local or global variables if they are non dereference, the garbage collector will do it. To empty a list you should use Clear(players$) instead.