forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   2D-программирование (http://forum.boolean.name/forumdisplay.php?f=109)
-   -   Как узать объект? (http://forum.boolean.name/showthread.php?t=4200)

dimanche13 16.11.2008 20:53

Ответ: Как узать объект?
 
oxid я это все знаю, спасибо. Сделал, наследованием от базового типа.
К тому же сделал класс, в котором можно добавлять типы и методы динамически во время выполнения программы. Тип содержит 2 поля список_полей и список_методов, а так же методы добавления, удаления и вызова методов и параметров. Получилось довольно забавно. :)
Код:

SuperStrict

Type _Unknown

        Field fields_map:TMap = New Tmap
        Field methods_map:TMap = New TMap
       
        Method add_method( name:String , func_callback( o:_Unknown, params:Object[] ) )
                methods_map.insert( name , New _Method.Create( func_callback ) )
        End Method
       
        Method add_field( name:String, this_type:Object )
                fields_map.insert( name , this_type )
        End Method
       
        Method get_field:Object( name:String )
                If fields_map.contains( name ) Then Return fields_map.ValueForKey( name ) Else Return Null
        End Method
       
        Method set_field( name:String , this_type:Object )
                If fields_map.contains( name ) Then
                        fields_map.insert( name , this_type )
                End If       
        End Method
       
        Method rem_field( name:String )
                If fields_map.contains( name ) Then
                        fields_map.remove( name )
                End If
        End Method

        Method rem_method( name:String )
                If methods_map.contains( name ) Then
                        methods_map.remove( name )
                End If
        End Method
       
        Method call_method( name:String , params:Object[] = Null )
                Local this:_Method = New _Method
               
                If methods_map.contains( name )
                        this = _Method( methods_map.ValueForKey( name ) )
                End If
                       
                this.callback( Self, params )
        End Method
       
        Method print_all_fields()
                For Local name:String = EachIn fields_map.keys()
                        Print name
                Next
        End Method
       
        Method print_all_methods()
                For Local name:String = EachIn methods_map.keys()
                        Print name
                Next               
        End Method
       
        Method clear_fields()
                fields_map.clear()
        End Method
       
        Method clear_methods()
                methods_map.clear()
        End Method
       
End Type

Local obj:_Unknown = New _Unknown

obj.add_field("x", New _Float.Create( 0.3 ) )
obj.add_field("y", New _Float.Create( 0.7 ) )

obj.add_method("add_x_with_y", add_x_with_y )

obj.call_method("add_x_with_y")

obj.set_field("x" , New _Float.Create( 8.3 ) )

obj.call_method("add_x_with_y")

obj.print_all_fields()
obj.print_all_methods()

obj.call_method("add_x_with_y", [ New _Float.Create( 0.5 ) , New _Float.Create( 0.9 ) ] )

End

Function add_x_with_y( o:_Unknown, params:Object[] = Null )

        Local x:Float
        Local y:Float
       
        If( params = Null )
                x = _Float( o.get_field("x") ).value
                y = _Float( o.get_field("y") ).value
        Else
                x = _Float( params[0] ).value
                y = _Float( params[1] ).value
        End If       
       
        Print ( x + y )

End Function


Type _Method

        Field callback( o:_Unknown, params:Object[] )
       
        Method Create:_Method( func_callback( o:_Unknown, params:Object[] ) )
                        callback = func_callback; Return Self
        End Method
       
End Type

Type _Type End Type

Type _Int Extends _Type
        Field value :Int
       
        Method Create:_Int( new_value:Int )
                value = new_value; Return Self
        End Method
       
        Method get:Int()
                Return value
        End Method       
End Type       

Type _Float Extends _Type
        Field value :Float
       
        Method Create:_Float( new_value:Float )
                value = new_value; Return Self
        End Method

        Method get:Float()
                Return value
        End Method       
End Type       

Type _Double Extends _Type
        Field value :Double

        Method Create:_Double( new_value:Double )
                value = new_value; Return Self
        End Method       

        Method get:Double()
                Return value
        End Method       
End Type       

Type _String Extends _Type
        Field value :String

        Method Create:_String( new_value:String )
                value = new_value; Return Self
        End Method

        Method get:String()
                Return value
        End Method       
End Type       

Type _Object Extends _Type
        Field value :Object

        Method Create:_Object( new_value:Object )
                value = new_value; Return Self
        End Method
       
        Method get:Object()
                Return value
        End Method       
End Type


oxid 17.11.2008 07:46

Re: Как узать объект?
 
Дык а что говоришь, что не решена?
Прикольно. Но не совсем оптимально. Я что-то подобное делал, только чуть по другому подошел к вопросу. Я функцию представил в виде класса, т.е. класс с одним методом CALL и массивом аргументов. Получается более обьекто-ориентировано. И код проще: имплиментируем нужные действия в наследнике класса функции - инициализировать с внешней функцией экземпляр не надо - просто создаем его и все. Можно еще синглтоном делать - будет типа меньше памяти занимать, но я с этим не заморачивался (там кое-что надо продумывать) и без синглтонов все нормально, если правильно организовать.
И еще насчет оптимизации (блин у тя оптимизировать и оптимизировать - хотел одно сказать, а там не одно):
1) If fields_map.contains( name ) Then - лишнее, сразу юзай fields_map.remove( name ) - лишнего не сотрет. Тоже и для методов. Проверку надо делать если действительно это надо (ну или для дебаг режима с проверкой) - значение возвращать там удален ли действительно или нет, но ИМО эт для отлдки надо обычно.
2) Обращение к динамическим полям и методам:
If methods_map.contains( name ) - не так - ты же дважды по списку проходишь и если он большой, то эт плохо.
Вот оптимальнее:
this = _Method( methods_map.ValueForKey( name ) )
if (this) then this.callback( Self, params );
Проверку на нуль быстрее делать, чем список проходить.
Вроде все ;)
ЗЫ: а простые типы тоже в объекты оборачивал :)

jimon 17.11.2008 10:50

Ответ: Как узать объект?
 
нафига делать то что делает транслятор за вас ?

dimanche13 17.11.2008 12:16

Ответ: Как узать объект?
 
Да, можно оптимизировать, просто я не думал здесь об оптимизации, выложил в удобном для восприятия виде. "имплиментируем нужные действия в наследнике класса функции - инициализировать с внешней функцией экземпляр не надо - просто создаем его и все." - а так, я кстати, делал для консоли(аля Quake) там очень много кода с отражением, вот приведу в нормальный вид и выложу.
А насчет "нафига делать" - действительно, нефига было делать :) , а что? напрягает?. Да и может пригодится кому...

jimon 17.11.2008 18:46

Ответ: Как узать объект?
 
просто не очень люблю программы которые себя пишут во время выполнения, но это мое имхо )

Randomize 21.07.2009 04:08

Ответ: Как узать объект?
 
Извиняюсь за некропостинг, но именно тут тема интересующая меня.
Решил написать чтоб форум не засорять.
Как я понял, есть список (TList) всех Field`ов обьекта.
Следовательно по ним можно пробежаться циклом.
А как допустим при этом "пробеге" понять ху из ху.
Я имею в виду какой Field Int какой Float.
Чтото типа GetFieldType.
И как оно отреагирует на массив или тип в фиелде?

dimanche13 21.07.2009 11:49

Ответ: Как узать объект?
 
почитай раздел Reflection в справке, очень поможет :) но только версия должна быть 1.30 или старше

Randomize 21.07.2009 13:53

Ответ: Как узать объект?
 
Цитата:

Сообщение от dimanche13 (Сообщение 111395)
почитай раздел Reflection в справке, очень поможет :) но только версия должна быть 1.30 или старше

Читаю как маньяк!
Мысли переполняются открытыми возможностями!
Вот это функционал. Да, вот это круто. Действительно BlitzMax с Blitz3D вобще нельзя сравнивать.
блин и где я смотрел :/
Огромнейшее спасибо.

Хммм... в итоге получается, что типы в BMAX тоже не совсем типы, но они чертовски удобны

SBJoker 21.07.2009 17:12

Ответ: Как узать объект?
 
Мда..как узнать тип...эх...

if String(a) print "This is a string!"

с типами аналогично:
if TMyType(a) print "This is a TMyType!"


Часовой пояс GMT +4, время: 22:36.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot