Type/function question

Blitz3D Forums/Blitz3D Beginners Area/Type/function question

lowpoly(Posted 2005) [#1]
Hi, hate to make my first post such a newb question, but this is the first roadblock I've been unable to work through. Basically, I want to pass a value to a function and use that value to work with an entity. Example code is something like this:

global box = createcube()

type foo
field xyz
end type

;main loop

a.foo = new foo
a\xyz = copyentity(box)

;*awesome unrelated code*

myFunction("xyz")

;end main loop

function myFunction(name$)
for a.foo = each foo
scaleentity "a\" +name$,100,100,100
end function

It seems simple enough, all I want to do is pass 'xyz' from the main loop to myFunction then take that value and tack on the phrase "a\" to the front so I can call and scale a\xyz from within the function.

Right now, all I get is 'entity not found' but if I replace the "a\"+name$ with a\xyz it works fine. When I send "a\" +name$ back to the main loop and call it, it also returns a\xyz...

So is it an issue with Type or because I'm working in a function, or what?

Racking my brain a bit so I'd really appreciate the help, thanks :)


big10p(Posted 2005) [#2]
The problem is that "a"+name$ is a string, not an entity handle. Just pass the type (containing the entity handle) to the function instead:

function myFunction(a.foo)
  scaleentity a\xyz,100,100,100
end function



Beaker(Posted 2005) [#3]
or alternatively just pass the entity itself:
xyz = copyentity(box)

;*awesome unrelated code*

myFunction(xyz)

;end main loop

function myFunction(entity)
scaleentity entity,100,100,100
end function



lowpoly(Posted 2005) [#4]
Thanks for the quick replies...

I have to wait until I get home to try this out, but from first glance I'm still a bit skeptical.

the two biggest factors are:

1. It has to remain as a type since there's actually a 'for' loop that dupes up to 8 copies per field.

2. I believe there is close to 12 fields I would need to run through this function.

because of those 2 points, it would be brilliantly easy if I could just specify the entity with the function and then call it 12 times from my main loop (to cover each field).

Sorry I wasn't clear before, I was hoping it was something simple like passing a string and not a handle. I would love to just send the entity like you suggested Beaker, but I think when I was struggling with this last night, it wasn't working as well: myFunction(a/xyz)


big10p(Posted 2005) [#5]
The example I gave does pass the type to the function. Inside the function, you can then access all the type fields. I don't think I understand exactly what it is you're trying to do. Can you explain a bit more?


lowpoly(Posted 2005) [#6]
to answer your question with another question, wouldn't passing the type as a whole force all the fields to inherit the same results? Unfortunately, I need each field's pass through the function to be able to work with unique parameters. I think I would lose that by passing the type rather than on a field by field basis.

so for instance, let's say I have my type with 10 fields.

each field goes through the function and brings with it a secondary, unique variable that will affect how the function works:

myFunction(a\xyz, 38) <-- where 38 is that unique variable I mentioned above.

so, if I sent the entire type through, then all 10 fields would be working with 38, which is what I don't want to happen. I need the function to be flexible.

Sorry if I am overcomplicating my explanation here :)


tonyg(Posted 2005) [#7]
Really not making much sense.
You either want to...
a) Apply '38' to a field of a type. Send the type and then access the field and 'action' 38 against it.
b) Apply '38' to *any* field of *any* type. Assign the value of the field to a varibale, send the variable, action 38 against it and return the result into the type field.
c) Apply '38' to a particular entity. Use object/handle.
d) something else...


big10p(Posted 2005) [#8]
to answer your question with another question, wouldn't passing the type as a whole force all the fields to inherit the same results?
You don't have to work on all the fields of the type from within the function - just the ones you want to affect. Hmmm, it's late and I still can't get a grasp of exactly what you want to do. :)

Are you saying all 10 fields are the same kind? e.g. all entity handles.

Maybe if you describe the actual task you want your program to achieve, we can then suggests methods. In your example, using "Type foo", "Field xyz", "Function MyFunction()" etc. doesn't help us understand what you're actually trying to do. ;)


lowpoly(Posted 2005) [#9]
heh sorry, the combination of me not being in front of my code and it being late for you guys isn't the optimal solution :D

the actual task is somewhat irrelevant; the function that I wrote works fine, but it *only* works with one specific field/entity handle. My goal was to be able to dynamically pass entity handles to the function so that I would have one master function, I could feed values to it and have it do it's magic. My original problem was just getting it understand "a/" +name$ is an entity handle and not just a string. But yes, all 10 fields are entity handles.

I guess my '38' example just made things worse... :)
what I was trying to say was if I have:

type foo
field a
field b
field c
...
field z

and I take each of those fields and pass their handle along through a function:

myFunction(a)

but I also want to pass a second value along with it:

myFunction(a,38)

then that's all well and good. The problem is, the number '38' is relevant only to 'a', whereas 'b' might be '6' and 'c' might be '200,000'

so my ultimate goal was to be able to do this:

myFunction(a,38)
myFunction(b,6)
myFuntion(c,200000)
...
myFunction(z,12)

so really what happens inside the function isn't as important to me right now as getting it to understand 'A' as the handle for the entity. My problem is less the application of the values and more just being able to call them by splicing together strings and variable names.

argh! sorry and thanks again for the help. This is what happens when you let artists program... :P


sswift(Posted 2005) [#10]
type monster
   field entity
   field health
end type

global thismonster.monster

thismonster = new monster
   thismonster\entity = createsphere()
   thismonster\health = 10

thismonster = new monster
   thismonster\entity = createcube()
   thismonster\health = 10

thismonster = new monster
   thismonster\entity = createcylinder()
   thismonster\health = 10

For thismonster = each monster
   SubtractHealth(ThisMonster)
next

Function SubtractHealth(ThatMonster.Monster)
   
   ; Make monster red, and reduce health by 1.
      EntityColor ThatMonster\Entity, 255, 0, 0
      ThatMonster\Health = ThatMonster\Health - 1

End Function


That's all there is to it. I create a bunch of monsters, I assign an entity to each, then I loop through all monsters I created and reduce their health by 1 and make them red.

That is how you access the fields of a type in a function. You pass a pointer to the type to the function. In doing that, you're not creating a new type instance, you are editing the data of the one you passed. Each variable that accesses a type is a pointer to a type, not the type itself. You can have 10 pointers pointing to the same memory allocated for a type. Only New allocates new memory for a new type.

PS:
Please excuse my code to create the entities, it's not right. I didn't bother to look up the function parameters for the functions to create primitives.

Also, you could have used ThisMonster.Monster as the function parameter, which I would normally do. Then when you use ThisMonster in the function you'd be using the pointer passed to the function not the global variable I declated. So they would not conflict with one another unless you tried to access the global in the functionm, which you probably have no reason to do. In fact, I didn't even need to make ThisMonster a global here.


Finjogi(Posted 2005) [#11]
lowpoly, there is no point to make function to assign one value to type field... just assign it "inline"

myfoo\a = 100
vs.
ChangeValueFunction(myfoo\a, 100)
or are you aftet this?
ChangeValueFunction(myfoo, "a", 100)
I think it is impossible to search match for "a" <-> myfoo\a ?

If you mean someting else I dont get it as you use 'a' for a fieldname and later on write 'a' as a handle for a entity.
So which way do you want it to do, pass a type, or a type field?

English is not my native lang, so sorry if I got it totally wrong :)


lowpoly(Posted 2005) [#12]
hey all, thanks for your input on this problem, I really appreciate the help.

I think the most important lesson I learned is to not ask for help when my code is not in front of me:) Naturally, when I got home, opened blitz and looked at what I had, I quickly realized what my mistake was :/

If you're interested, here's how I solved my problem:

Going back to my first post's code, it came down to taking the For/Each/Next loop out of the function and sandwiching it around myFunction(xyz) in the main loop. This way the entity handle for XYZ got passed and parsed individually through the function. This ended up being the best way for isolating what I wanted to perform and now it works perfectly.

Lesson learned, I should have just posted my actual code and avoid confusing everyone :) sorry, but thanks for the effort!


Sir Gak(Posted 2005) [#13]
The best solutions are those where you figured out the problem and the solution by yourself. A solution just handed over to you by someone else may or may not teach you. Resolving it yourself allows you to know how to fix it the next time that kind of problem comes up.

So, kudos to you for figuring it out yourself!

(P.S. Of course, when you're stuck, a helpful hand is sometimes all you need to see the light, like the saying, You can't see the forest for the trees, meaning, you're too close to the problem to see the solution.)