GLBasic forum

Main forum => GLBasic - en => Topic started by: bigtunacan on 2012-Aug-07

Title: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-07
I've creating an ANIMATION type that I use to store a single animation loop, then I assign multiple ANIMATIONS to a character and switch between these based on the state of the character.

Initialization looks something like this.
Code (glbasic) Select

ANGEL = FILE_LOADANIM("/Animations/Ubi/", "angel" + UBI_INDEX + ".xml")
FATSPR = FILE_LOADANIM("/Animations/Ubi/", "fat" + UBI_INDEX + ".xml")
FIRESPR = FILE_LOADANIM("/Animations/Ubi/", "fire" + UBI_INDEX + ".xml")
HITSPR = FILE_LOADANIM("/Animations/Ubi/", "hit" + UBI_INDEX + ".xml")

STATE = UBIFALLSPR
   

Then I try doing a comparison something like this.
Code (glbasic) Select

IF UBISTATE = UBIFALLSPR    // THIS ALWAYS RETURNS FALSE :(
UBIPOSY%=UBIPOSY%+1
ENDIF


I'm guessing that when I do the assignment it is actually creating a new object and the comparison is just checking if they are the same object.  Is there a way to do this as more of a BYREF style assignment and have my comparison come back as I expect?
Title: Re: Copying and comparing TYPES?
Post by: MrTAToad on 2012-Aug-07
The easiest way would be do to a comparison function in the type...
Title: Re: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-08
I'm trying to do a copy by reference though.  I want to do something like this; of course this does not work it really is just doing a new object inside the function and then assigns that back to the passed in reference.  I'm looking for an ASSIGN by reference functionality; I want variable A to point to the address of variable B, so that if I update attributes on A they are reflected in B and vice versa.

Code (glbasic) Select

TYPE ANIMATION
  SOME
  VARIABLES
  HERE

  FUNCTION copy:  foo AS ANIMATION
    foo = self
    return foo
  ENDFUNCTION

ENDTYPE


When I tried to do that I received compiler errors
Code (glbasic) Select

In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:2:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:110: error: `DGInt __GLBASIC__::ANIMATION::copy' is not a static member of `class __GLBASIC__::ANIMATION'
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:110: error: `Anything' was not declared in this scope
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:111: error: expected `,' or `;' before '{' token
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp1.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp2.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp3.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp4.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp5.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp6.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
*** FATAL ERROR - Please post this output in the forum
Title: Re: Copying and comparing TYPES?
Post by: bigsofty on 2012-Aug-08
I don't really understand the question but the syntax is wrong for GLB. GLB needs to know what type you are returning from a function.

So this...
Code (glbasic) Select
  FUNCTION copy:  foo AS ANIMATION
    foo = self
    return foo
  ENDFUNCTION

becomes this...
Code (glbasic) Select
FUNCTION copy AS ANIMATION: foo AS ANIMATION 
    foo = self
    RETURN foo
  ENDFUNCTION

which could be shortened to this...
Code (glbasic) Select
FUNCTION copy AS ANIMATION:
    RETURN self
  ENDFUNCTION
Title: Re: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-08
Sorry; that was just some untested sample code, you are right that it should be slightly different, but the issue remains the same. 

Here, I will try to provide a better example using the same function.

Code (glbasic) Select

TYPE ANIMATION
  VAR1
  VAR2

  FUNCTION copy AS ANIMATION:
    RETURN self
  ENDFUNCTION

  FUNCTION init:
    // set some vars here...
    VAR1 = 1
    VAR2 = 2
  ENFUNCTION
ENDTYPE


A AS ANIMATION
B AS ANIMATION
A.init()
B = A.copy()
B.VAR1 = 3

PRINT A.VAR1, 0, 0
PRINT B.VAR1, 0, 200


This would print to the screen

Code (glbasic) Select

1
3


This is because the B = A or B = A.copy() results in a new TYPE instance being created for B with a copy of the values from A.  At the point in time that I make the copy; they look the same, but they are really clones, not 1 same object.  Changes made to A do not update B and same for changes to B do not update A.  This is a VALUE copy.  I'm wanting a REFERENCE copy; so I would like B = A to really just mean that B POINTs TO A; just as we would do using pointer logic in C/C++. 

Maybe this is possible only through some inlining of C++ code into my game, but I am hoping this is not the case and there is some type of simple pointer based assignment in GLBasic that i just am unaware of?
Title: Re: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-08
I tried to do this directly in C++ using INLINE like this

Code (glbasic) Select

FUNCTION copyanim: a AS ANIMATION, b AS ANIMATION
INLINE
a = &b;
ENDINLINE
ENDFUNCTION


I expected this would actually work, but it fails to compile!

Code (glbasic) Select

IncrediBuild skips: UpUpUbi.gbas, Globals.gbas, jolib2.gbas, Ubi.gbas, VolcanoIsland.gbas, xmlparser.gbas,
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp1.cpp: In function `DGInt __GLBASIC__::copyanim(__GLBASIC__::ANIMATION&, __GLBASIC__::ANIMATION&)':
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp1.cpp:115: error: no match for 'operator=' in 'a = +b'
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:131: note: candidates are: __GLBASIC__::ANIMATION& __GLBASIC__::ANIMATION::operator=(const __GLBASIC__::ANIMATION&)
*** FATAL ERROR - Please post this output in the forum
Title: Re: Copying and comparing TYPES?
Post by: MrTAToad on 2012-Aug-08
Thats because there is no equality routine in the type when compiling :)
Title: Re: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-08
This just confuses me more.  I'm not trying to do a comparison in my inline C++; I'm trying to do a simple pointer assignment. 
Title: Re: Copying and comparing TYPES?
Post by: bigsofty on 2012-Aug-08
Could you just not stick your ANIMATION types in an array, then use a State variable as an index?

Something like this...

Code (glbasic) Select
TYPE ANIMATION

  spriteBase%
  currentFrame%
  frames%[]

  FUNCTION load: filename$
  ENDFUNCTION

  FUNCTION animate:
  ENDFUNCTION

ENDTYPE

CONSTANT falling = 0
CONSTANT jumping = 1

GLOBAL state = falling

GLOBAL a[] AS ANIMATION
DIM a[2]

a[falling].load("falling.xml")
a[jumping].load("jumping.xml")

a[state].animate()

IF state=falling THEN blah...

Title: Copying and comparing TYPES?
Post by: Kitty Hello on 2012-Aug-08
Uhm

Function copy: a as T, b as T
a=b
Endfunction

Local a as T, b as T
b.val=100
copy(a,b)

this should work.

Title: Copying and comparing TYPES?
Post by: Kitty Hello on 2012-Aug-08
Ah. Silly me. You need a reference? What for?
Alias would generate a reference.
Title: Re: Copying and comparing TYPES?
Post by: Slydog on 2012-Aug-08
I ran into the 'how do a get a reference to a type' issue a year or so ago.
I have my own 'Font' type specifying settings for each one of my fonts (including the graphics file).

I also created my own 'Gui' type, and wanted each gui element to have a 'font' setting.
After researching this for a bit I realized GLBasic doesn't offer references, just copies.
So each of my gui elements (buttons, labels, etc) had a COPY of each font object, a huge memory waste.
(Only evident after making changes to the master font instance, and noticing the copies weren't changing too?!)

What I did (kinda kludgy) was instead store a font 'id' in each element, and have a font lookup based on id (or a font array and the id is the index).

I have used ALIAS in other situations, but wasn't clear or apparent it could be used in these situations.
Title: Re: Copying and comparing TYPES?
Post by: bigsofty on 2012-Aug-08
One problem with Alias is that you cant copy and store the value in a variable, it will copy the what its pointing to instead.
Title: Re: Copying and comparing TYPES?
Post by: Slydog on 2012-Aug-08
So, do we need a new GLBasic command? (ie 'BYREF')

Code (glbasic) Select
LOCAL one AS TFoo // Normal TFoo instance
LOCAL two AS TFoo // Normal TFoo instance
LOCAL three AS TFoo BYREF // Reference to a TFoo instance

one.parameter = 49
two = one
three = one
one.parameter = 72
DEBUG two.parameter // Prints "49"
DEBUG three.parameter // Prints "72"


[Edit] But what do you do if you reference 'three' before it has been assigned?
It would be 'null' and therefore you would need a new error 'BYREF Variable not assigned!' or something.
Title: Re: Copying and comparing TYPES?
Post by: MrTAToad on 2012-Aug-09
You can't really reference TFoo as its just a type definition.

For a comparison, you would have to write your own routine, something like :

Code (glbasic) Select
TYPE Ta
a%;b%;c%

FUNCTION compare%:b AS Ta
IF self.a%=b.a% AND self.b%=b.b% AND self.c%=b.c%
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION
ENDTYPE
Title: Re: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-09
I'm not trying to reference the type definition so much as I am trying to reference an INSTANCE of the the type definition.  Like Slydog said; it is a huge waste of memory to have to create many copies in memory of the same object; this is what I'm trying to avoid.  I'm releasing on so low end Android devices too so my memory is cherished resource. 

@Kitty Hello,
     I just tried the ALIAS command and it doesn't seem to work quite right.  Maybe it has problems when trying to alias to TYPEs rather than a simple data type? but definitely was not correctly pointing to the object :(
Title: Re: Copying and comparing TYPES?
Post by: kanonet on 2012-Aug-10
ALIAS works correct for me:
QuoteLOCAL a AS Tmytype
ALIAS b AS a
This works too:
QuoteLOCAL a AS Tmytype
ALIAS b AS a.id
But ALIAS has one limitation, this does not work:
QuoteLOCAL a AS Tmytype
LOCAL b AS Tmytype
ALIAS b.a AS a

Did you try the last one or had problems with one of the other samples? Basically atm you can just store a pointer in a variable with normal datatype (you dont need to define it before the alias, its local by default), but you cant store the pointer in a type, which would be great.
Title: Copying and comparing TYPES?
Post by: Kitty Hello on 2012-Aug-10
Alias makes a variable that points to (=reference) whats right of the "as" argument. You cannot hold references in types. Also reference pointers might break if you point into an array element and reallocate the container (dimpush, dimdel, ...)
Title: Re: Copying and comparing TYPES?
Post by: bigtunacan on 2012-Aug-11
Here is my fully implemented TYPE
Code (glbasic) Select

TYPE ANIMATION
ID // This is a unique identifier for this particular animation
ANIM_INDEX // This is the sprite index
CURR_FRAME
NUM_FRAMES
NAME$
STEPTIME% // delta step for fixed or absolute time to finish
LAST_UPDATE_TIME
TIMESTEPMODE
LOOPMODE

FUNCTION draw:x%,y%
DRAWANIM self.ANIM_INDEX, self.CURR_FRAME, x%, y%
ENDFUNCTION

FUNCTION init: index%, width%, height%, name$
self.ANIM_INDEX=index%
self.CURR_FRAME=0

LOCAL sx%,sy%
GETSPRITESIZE index, sx%, sy%
self.NUM_FRAMES = sx%/width%
self.NAME$=name$
self.STEPTIME%=100
self.LAST_UPDATE_TIME = MASTERTIMER
self.LOOPMODE=LOOPFOREVER
ENDFUNCTION

FUNCTION anim:
IF(GETTIMERALL() > (self.LAST_UPDATE_TIME + self.STEPTIME%))
self.CURR_FRAME = IIF(self.CURR_FRAME>=(self.NUM_FRAMES-1), 0, self.CURR_FRAME+1)
self.LAST_UPDATE_TIME = GETTIMERALL()
ENDIF
ENDFUNCTION

FUNCTION is_equal: an AS ANIMATION
IF an.ID = self.ID
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION

ENDTYPE


I create my first TYPE like so
Code (glbasic) Select

UBIFALLSPR = FILE_LOADANIM("/Animations/Ubi/", "falling" + UBI_INDEX + ".xml")


After this I do my alias

Code (glbasic) Select

ALIAS UBISTATE AS UBIFALLSPR


In an update statement I call UBISTATE.anim() so that whatever I'm currently pointing to should animate.

When I call UBISTATE.draw(x,y) nothing shows up on screen.

If I do the same directly as UBIFALLSPR.draw(x,y) it shows up fine and is animating correctly (anim is still called on UBISTATE); so it seems something is being corrupted.