some max OO help please.

BlitzMax Forums/BlitzMax Beginners Area/some max OO help please.

Grey Alien(Posted 2006) [#1]
OK this is probably a dumb question but, I wanted to wrap TSound by adding some extra useful functions and properties to it, but I still wanted my new type to work exactly the same, and with the same functions as TSound (e.g. PlaySound etc) - so I started with this:

Type ccSound Extends TSound
	Field test:ccSound
	
	Method LoadSample:ccSound(ThePath$, LoopFlag%)
		test = LoadSound(ThePath$, Loopflag)
		If Not Self Then
	    	ccRunTimeError ("Error loading sample "+ThePath$)
		End
		Else 
    		Return Self			
	  	EndIf		
	EndMethod
EndType


This line "test = LoadSound(ThePath$, Loopflag)" produces the following compile error: "unable to convert from Tsound to ccSound".

Actually originally I didn't have "test", I just put "self = LoadSound(ThePath$, Loopflag)" but this generates the following compile error: "expression must be a variable".

Well I understand that TSound and my ccSound are not the same, but I thought that as ccSound is inherited from TSound, self would be OK, but it isn't. I guess that all the sound functions would also fail with ccSound passed in as well as it isn't able to typecast ccSound as TSound, am I right?

Is the way to solve this to craply have a Field within the ccSound type called TheSound:TSound, and assign my LoadSound to that and then whenever I call any sound functions do it like this:

MySound:ccSound
'pretend I've loaded now
PlaySound(MySound.TheSound)


Thanks in advance, hope this makes sense!


Dreamora(Posted 2006) [#2]
ccSound(loadsound(...)) should work, not?
You need to manually typecast between objects.


Grey Alien(Posted 2006) [#3]
oh yeah cool, that's how I typecase in Delphi. Thing is this

self = ccSound(LoadSound(ThePath$, Loopflag))

still gives the "expression must be a variable" error. What's that about then? I guess you can't reassign/set self within itself! Can only New set Self?

[edit]whoa, If I make a TSound variable called X and then call X.Load("blah.wav"), Load returns a TSound pointer, but does it NOT set X to point to the returned pointer? Do I need to go X = X.Load("blah.wav")? In which case I can change my code in the first post to return a ccSound pointer and just do MySound = MySound.LoadSample("foo") which is pretty crap as I'm converting a standalone global function that I could call as MySound = ccLoadSample("foo"). I was trying to avoid tons of global functions not attached to objects, oh well.


Also I guess I could get Playsound to work by typecasting as follows:

playsound(TSound(MySound))
where my sound is a ccSound. However, this is pretty much as lame as writing MySound.TheSound, oh well.


Dreamora(Posted 2006) [#4]
Hmm no normally you would not need to assign it, at least if you aren't interested in it.


Grey Alien(Posted 2006) [#5]
I guess I should test it. If I make a local Tsound variable X and then call X.Load("Y") if X hasn't been updated by Load, then surely PlaySound(X) or X.Play will fail? If they don't fail because X is set by Load(), then this means that BlitzMax IS able to redefine what Self points at somehow!

Can you view the source code for the modules anywhere? Then I could look at how TSound.Load works.


Dreamora(Posted 2006) [#6]
Does that work?
Type ccSound
  field sound:TSound

  method loadsound(path:string, flag:int)
    sound = ....

  end method

  method playSound()
    playsound(sound ...)
  end method
end type


Perhaps the extend is causing the problem as you add fields and load the sound to a field within your extended sound instead of ccSound variable itself.


Grey Alien(Posted 2006) [#7]
yeah that code snippet works. Maybe I'll go with that for now thanks.


Grey Alien(Posted 2006) [#8]
OK I tested this:

	Local X:TSound = New TSound
	X.Load("data\SplashSound.wav", True)
	X.Play


and nothing plays whereas

	Local X:TSound = New TSound
	x = X.Load("data\SplashSound.wav", True) 'this line is different
	X.Play


works. I get it now. The method Load is part of the Type but does NOT ACT on an instance, which is why X= is needed at the start of the line. This means that Self is NOT being reassigned. Fair enough.


Yan(Posted 2006) [#9]
I know you've sort of sussed it already, but just to clarify.

TSound.Load is a function that returns a TSound type, not a method.

So, you'd use...
local sound:TSound = TSound.Load("data\SplashSound.wav", True)
local chan:TChannel = sound.Play()
...ETC...



Grey Alien(Posted 2006) [#10]
yeah thanks, that helps too. Thing is how do you know its a "function" and not a "method" that acts on the instance from the manual?


Yan(Posted 2006) [#11]
The definitions for most of the the system types methods and functions can be found in the relevant modules docs (usually at the bottom).

For those that aren't documented, it's a trip to the modules source.


Grey Alien(Posted 2006) [#12]
oh yeah just noticed the manual calls Sound.PLay a method (which it is) and Sound.Load a function. Fair enough, I just didn't spot that.