create a new unknown type?

BlitzMax Forums/BlitzMax Programming/create a new unknown type?

slenkar(Posted 2008) [#1]
i have a funcion that accepts a type object but it doesnt know what kind.....
function make_another(mytype:object)

end function



how do i make a new type instance of the same type as the incoming object?


Azathoth(Posted 2008) [#2]
If you don't need reflection you can use 'New mytype' and it will create a new instance even if the function doesn't know what type 'mytype' is.

function make_another(mytype:object)
  Local copyoftype:object=New mytype
end function



slenkar(Posted 2008) [#3]
thanks

EDIT- hmm it didnt work
when I try to modify a field it says the field doesnt exist


Azathoth(Posted 2008) [#4]
What do you mean? The function wouldn't be able to modify the field if it doesn't know what the type is. You could use reflection or have all your objects inherit from a base class.


slenkar(Posted 2008) [#5]
if i had them inherited from the base class how would i do it?


Azathoth(Posted 2008) [#6]
Such as
Type BaseType
	Field whatever:Int
EndType

Type SomeType Extends BaseType

EndType

Function make_another(mytype:Object)
	Local a:BaseType=BaseType(New mytype)
	
	Assert a,"Not of BaseType"
	
	a.whatever=10
End Function


However you need to make sure all types that are passed inherit from BaseType, the Assert only tests in debug mode.


slenkar(Posted 2008) [#7]
thanks,that worked

do you know how I would create a method or function in the base type
that would create a new instance of the extended type?

e.g.



I found this command in reflection that will help me:
DerivedTypes:TList()

but im not sure how to use it


N(Posted 2008) [#8]
For reference, I refer to types as 'classes' throughout this post. Mentioning that since a lot of people I've talked to are confused by that.



This'll make a new one of anything. It's simple, and I don't know why you'd need to do this when you seem to have no need for a shallow or deep copy of an object, so who knows.

As for the second, you could also do that with reflection fairly easily, but you might have to have some means of distinguishing the difference between two classes that inherit from the same base class. If you have only one class and only ever will have one class that extends a base class, then you should just merge the two into a single class.


slenkar(Posted 2008) [#9]
thanks,

do you know how I could use:
DerivedTypes:TList()

to go through a list of derived types and see which type the unknown type is?

I still need to modify a field from the unknown type


N(Posted 2008) [#10]
to go through a list of derived types and see which type the unknown type is?

You already have its type ID right there, so you know what it is. Am I missing something that you think is obvious but isn't?

I still need to modify a field from the unknown type

You can check for and set a field like this.
Local fooble:Foo = New Foo
Local id:TTypeID = TTypeID.ForObject( fooble )
Local someField:TField = id.FindField("someField")

If someField Then
    someField.Set( fooble, "0.25" )
EndIf

Just to make a point, all of this is in the documentation.


Dreamora(Posted 2008) [#11]
And to mention anothe thing: Reflection is slow.

If you have no idea what type it is, your code might need a little rework to have at least a basic knowledge.
Don't push through Object but an own baseclass that offers the very basic it must offer (or an abstract base class that works as an interface by defining all functionality that the extended types must have)


Azathoth(Posted 2008) [#12]
do you know how I would create a method or function in the base type
that would create a new instance of the extended type?
Something like this?

Type BaseType
	Field whatever:Int
	
	Method MakeNew:BaseType()
		Return New Self
	EndMethod
EndType

Type SomeType Extends BaseType

EndType


Local a:SomeType=New SomeType
Local b:SomeType=SomeType(a.MakeNew())



slenkar(Posted 2008) [#13]
well originally i had a list of tasks that could be completed in 2 ways each:

type task
field first_solution:task
field second_solution:task
field description$
end type

my game was written in Blitz3d using only 2d commands so I transferred the project over to blitzmax quite easily.

each solution had a pointer to a different new task. So, if you completed a task in a certain way it would change the story.

Then I used XML notepad to design the structure of the tasks.

then I used a different type for each game character that was handing out the tasks

e.g.
type wizards_tasks extends task
field first_solution:wizards_tasks
field second_solution:wizards_tasks
end type

this was a convenient way of being able to get to the first in the list.(using the first command)

then I didnt want to write a new function to read each characters tasks in the xml file.

so I created this function

function read_children(xmlnode,parent_pointer:object)

end function

to recursively read all the tasks,in the xml file and create new type instances.for the first and second solutions.
but I didnt know which type was being used at the time,

I may have to just merge all the tasks into the same type,
but i was afraid that was going to slow the game down going through every single task each time to find one.


Dreamora(Posted 2008) [#14]
Sounds like using TMap would be step one so you can easily check for "TaskXY" instead of iterating till the end of the world.

The alternative is an Array of tasks and store the index of the task within those fields for example.

But here the problem is quite obvious: You don't need to put in first_solution and second solution anymore on the extended task, only things they need to know as wizard tasks actually that is "above" the basic task knowledge.
Because then you can "fire" the task by using the Type TTask method for executing the task or howere you planned that to make it work.

The wizard task then just would reimplement the same method so it works in the "wizard" way ...

But I might missunderstand at what you attempt.