Можно ли назначить анонимную функцию свойству глобального ассоциативного массива?

Новое в разработке roku / brightscript: можно ли добавить объект в глобальный ассоциативный массив (доступный для всех компонентов), у которого есть метод, определенный как одно из свойств, и вызвать этот метод?

Main.brs:

function Main()
    init()
end function

function init()    
    screen = createObject("roSGScreen") 
    m.port = createObject("roMessagePort")
    screen.SetMessagePort(m.port)

    scene = screen.CreateScene("MainController")
    screen.show()

    o = {
        getName: function() as string
            return "John"
        end function
    }

    setUpGlobal(screen)
    m.global.addFields({mainMethods: o})        

    while(true)
        msg = wait(0, m.port)
        msgType = type(msg)

        if msgType = "roSGScreenEvent"
            if msg.isScreenClosed() then exit while
        end if    
    end while        
end function

function setUpGlobal(p_screen as Object)
    m.global = p_screen.getGlobalNode()
    m.global.id = "GlobalNode"
end function

.. затем в другом MainController, после выполнения задачи и возврата данных ...

MainController.brs

function init()
    loadConfig()
end function


function loadConfig()
    m.config = createObject("roSGNode", "Configurator")
    m.config.observeField("done", "onConfigLoaded")
    m.config.observeField("fail", "onConfigError")
end function 


function onConfigLoaded()
    print "config loaded: " + m.global.mainMethods.getName()
end function


function onConfigError()
    print "config failed to loaded"
end function

Когда он попадает в строку 16 MainController, я получаю следующее:

Функция-член не найдена в компоненте или интерфейсе BrightScript. (ошибка времени выполнения и hf4) в pkg: /components/MainController.brs (16)

Это просто общий тест того, что можно / нельзя сделать, поэтому, пожалуйста, не комментируйте, является ли это «хорошей практикой» или нет. Я просто хочу знать, возможно ли это, и если да, то что мне здесь не хватает? Спасибо за любую помощь


person neoRiley    schedule 20.12.2016    source источник


Ответы (3)


Вы можете использовать функции как roAssociativeArray значения. Фактически, именно так и выполняются объектно-ориентированные методы в BrightScript.

Однако вы не можете назначать функции полям объекта Roku Scene Graph (roSgNode производные)! Либо прямо, либо косвенно (вложенные). Это ограничение (текущей ?!) реализации.

Вы можете увидеть список типов полей, поддерживаемых RSG, здесь https://sdkdocs.roku.com/pages/viewpage.action?pageId=1608549

Да, там говорится о поддержке assocarray и (в последнее время) array - но к этому есть предостережение! Когда вы назначаете (или даже обращаетесь) к составным объектам между потоками, создается глубокая копия, и только «поддерживаемые» типы проходят через нее - и, как вы поняли, function не является одним из них. Все нераспознанные данные в настоящее время удаляются незаметно, даже без предупреждения, так что покупатель остерегается.

См. https://forums.roku.com/viewtopic.php?f=34&t=96955&p=541965#p541965, чтобы узнать больше. Почувствуйте приглашение добавить свой голос на форум разработчиков Roku, запросив поддержку типа функции со стороны RSG - они, как правило, выслушивают, если достаточно людей жалуется.

person Nas Banov    schedule 21.12.2016
comment
Отметив это как ответ - спасибо за подробное объяснение! Зайду на форумы ... :) - person neoRiley; 22.12.2016

Вы не можете передавать функции в полях узла. Только данные. Если вы проверите значение m.global.mainMethods.getName сразу после его установки, оно будет недействительным.

person Eugene Smoliy    schedule 21.12.2016
comment
Большое спасибо - в документации действительно говорится, что возвращается объект roSGNode, как описано в getGlobalNode () docs - я думаю, что путаница возникает, когда в документации говорится, что вы можете назначать анонимные функции как значения в roAssociativeArray, а затем в документации для roSGNode говорится, что он реализует / поддерживает ifAssociativeArray ( roSGNode docs). При тестировании я могу убедиться, что любой метод, переданный в global, определенно недействителен. Обозначение как ответ. - person neoRiley; 21.12.2016

Я думаю, вы можете сделать это с помощью анонимных функций.

https://developer.roku.com/en-gb/docs/references/brightscript/language/program-statements.md#anonymous-functions

q = { 
    starring : Function(o, e)
        str = e.GetBody()
        print "Starring: " + str 
        toks = box(str).tokenize(",")
        For Each act In tok
            actx = box(act).trim()
            If actx <> "" Then
                print "Actor: [" + actx + "]"
                o.Actors.Push(actx)
            End If
        End For
        Return 0
    End Function 
} 

q.starring(myobj, myxml)
person Jonny    schedule 21.08.2019