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 19.08.2007 19:47

Как узать объект?
 
Ну есть у меня например ф-ция для триггера:
function Trigger(x:int,y:int, ob:object), которая должна изменять состояние объекта ob.
как взять ссылку на этот объект, что бы изменить внутренние его поля ob.x = 1 или использовать методы ob.choose() ?
Я сделал так, в самом объекте написал метод get() ,который возращает себя (return self), но это работает только если, я жестко указываю в объявлении функции тип объекта(TMyObj)
function Trigger(x:int,y:int, ob:TmyObj)
Возможно ли сделать как-нибудь по-другому? то есть универсальную функцию, а не набор из
function TriggerObj1(x:int,y:int, ob:TmyObj1) ..
function TriggerObj2(x:int,y:int, ob:TmyObj2) ..
function TriggerObj3(x:int,y:int, ob:TmyObj3) ..

johnk 19.08.2007 20:27

Re: Как узать объект?
 
Сделай из нее метод, и будет тебе счасьте.

dimanche13 19.08.2007 20:31

Re: Как узать объект?
 
чего???

johnk 19.08.2007 20:41

Re: Как узать объект?
 
Ну тут не такой подход нужен. Здесь нужно методами все это промышлять.

dimanche13 19.08.2007 21:18

Re: Как узать объект?
 
ну поделись своим методом...

jimon 19.08.2007 21:26

Re: Как узать объект?
 
кури вот так
Код:

Type TmyObj
field lol% = 1

method Trigger(x:int,y:int)
debuglog lol
end method

End Type

local a:Tmyobj = new tmyobj
a.Trigger(0,0)


johnk 19.08.2007 21:27

Re: Как узать объект?
 
Ну если я правильно мыслю, то все по типу:

Есть тип Object

Цитата:

type Object
field x
field y
end type
Набираю в броузере, могу ченить напутать.
Ну и сменять их методом:
Цитата:

type Object
field x:int
field y:int
Method Triger(nx:int,ny:int)
x=nx
y=xy
end Method
end type

Так и так, придется набирать :) Сэкономить нажатие клавиш вроде не получится.

dimanche13 19.08.2007 21:32

Re: Как узать объект?
 
Пилять, может я что-то не так объяснил. Все что вы пишите, я и так знаю. Я говорю тип триггер , в который можно передавать любой объект вот что меня интересует.
2JohnK type object - не скомпилится ,потому что это два зарезервированных слова.

jimon 19.08.2007 21:40

Re: Как узать объект?
 
dimanche13
юзай наследие
Код:

Type Trigger

 field obj:TImage

 method Trig(x,y)
  drawimage obj,x,y
 end method
End Type

Type Trigger1 extends Trigger
 field blablabla%

 method Something()
  Trig(0,0)
 end method
End Type

любой обьект будет Object
function myfunc(my_variable:Object)
end function

dimanche13 19.08.2007 22:40

Re: Как узать объект?
 
В общем я понял. Я плохо объяснил, что хочу. И никто мне не поможет, кроме себя самого. Всем спасибо. Все свободны.

ICoder 27.10.2008 17:42

Ответ: Как узать объект?
 
Несмотря на давность темы - решил оживить её. Вот один вариант:
Код:

Type TA
        Field x%, y%
        Field str$="This is type A"
EndType

Type TB
        Field x%, y%
        Field str$="This is type B"
End Type

Type TC
        Field x%, y%
        Field str$="This is type C"
End Type

Function Func(obj:Object)
        If TA(obj) Print TA(obj).str
        If TB(obj) Print TB(obj).str
        If TC(obj) Print TC(obj).str
End Function

Local aaa:TA=New TA
Local bbb:TB=New TB
Local ccc:TC=New TC

Func(ccc)
Func(aaa)
Func(bbb)

Я вот хотел создать тему с таким вопросом... Так что, если у кого есть дельное решение данного вопроса - напишите, please! :wild:

Черный крыс 03.11.2008 12:10

Ответ: Как узать объект?
 
Любой пользовательский обьект экземпляра - есть не что иное - как расширенный Object - их можно привести друг в друга.

Для общих случаев юзай обьекты.
Здесь тип Object - выступает неким "мостиком" который хранит указатель на обьект класса.
Для частного случая, когда необходимо точно узнать триггер это или например лифт, то просто приводим этот обьект в пользовательский тип, если результат не равен нулю - значит попали....=)

ICoder 03.11.2008 18:18

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

Сообщение от Diablo1909 (Сообщение 89982)
Для общих случаев юзай обьекты.

Т.е. лучше прямо обращаться к какому-либу объекту по его имени, чем посредством "мостика" (Object)??? ;)

dimanche13 04.11.2008 11:20

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

oxid 16.11.2008 14:31

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

Сообщение от dimanche13 (Сообщение 90032)
Да, это все понятно, что вы говорите, суть проблемы была - загнать любой тип данных в функцию, и проблема до сих пор не решена. А к какому типу принадлежит объект можно и select-ом узнать.

Ужос просто. Еще не решена.:wallbash:
Есть такое понятие - иерархия классов, оно подразумевает некий базовый класс (в идеале полностью абстрактный) от которого наследуются все остальные.
Проблема решается 2мя способами - перегружаемыми функциями или с помощью ООП.
1. Перегружаемых функций в БМ нет. Их можно сделать ручками, что неудобно. Этот вариант ты уже написал в самом первом посте. Все это гимор и останавливаться на этом не буду.
2. ООП. Тут есть где разгуляться:
2.1. Определение типов и приведение типов - уже описывали. Могу добавить что появился класс, который играет роль своеобразного указателя на класс объекта, что криво, но лучше что-то чем ничего. Ну и вообще основное его назначение не это, а отражения (reflection). И имя ему TTypeId. И плавно переходим к
2.2. Отражения. С помощью TTypeId можно определить класс и вызвать метод или обратиться к полю по имени. А также проверить есть ли нужное поле в классе, по его имени - Method FindField:TField( name$ ). Это подойдет ну для любого класса.
2.3. Иерархия (ИМО самый правильный и переносимый способ). Наследуем все нужные для работы классы от базового, в котором прописываем нужные общие поля и методы (абстракция в БМ есть). Аргументом передаем базовый тип, с которым можно делать то, что нам нужно.
Пжалуста.:cool:

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:26.

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