ImageIO

Версия Minecraft
0.1+
1,111
47
420
Крч есть у меня такой вот код:
Scala:
override def bindTexture(resource: Resource): Unit = {
    if (!resource.isTexture) throw new RuntimeException(s"$resource is not a texture")
    textures.get(resource) match {
      case Some(texture) =>
        texture.bindAsTexture()
      case None =>
        getInput(resource) match {
          case Some(input) =>
            val image = ImageIO.read(input)
            val unit = image.toGLTexture
            textures.put(resource, unit)
            unit.bindAsTexture()
          case None =>
            bindTexture(emo)
        }

    }
  }
Да, да тригеритесь на скалу. Суть в том что он должен был бы загрузить картинку из потока, но он тупа даже не входит в метод read (ImageIO.read(input)). Вопрос собсвенна пачему?
 

CumingSoon

Местный стендапер
1,634
12
269
Мы же не в энтерпрайзе. В играх важен перфоманс, а не генераторы мусора на каждом шагу. Очистка - не быстрая операция.
О, вторая волна. Погодить-ка, сделаю за попкорном
 
7,099
324
1,510
Вопрос собсвенна пачему?
getInput возвращает None
Да, да тригеритесь на скалу.
Scala:
override def bindTexture(resource: Resource): Unit = {
    if (!resource.isTexture) throw new RuntimeException(s"$resource is not a texture")

    textures.getOrElse(resource,{
         val input=getInput(resource)//Если оно None, то в  ImageIO.read не пойдет
         input.map(input=>{
           val image = ImageIO.read(input)
           val unit = image.toGLTexture
           textures.put(resource, unit)
           unit
        }).getOrElse(emo)
    }).bindAsTexture()

  }
 
Последнее редактирование:
7,099
324
1,510
Наверное. Но Красная книга рекомендует юзать функции высшего порядка, значит, нормально будет.
 
1,111
47
420
getInput возвращает None

Scala:
override def bindTexture(resource: Resource): Unit = {
    if (!resource.isTexture) throw new RuntimeException(s"$resource is not a texture")

    textures.getOrElse(resource,()=>{
         val input=getInput(resource)//Если оно None, то в  ImageIO.read не пойдет
         input.map(input=>{
           val image = ImageIO.read(input)
           val unit = image.toGLTexture
           textures.put(resource, unit)
           unit
        }).getOrElse(emo)
    }).bindAsTexture()

  }
Но если бы оно было None, оно бы попыталось привязать emo, не было бы emo, краш с переполненым стэком. А в моем случае просто не выходит из метода совсем. Твой код не соответствует моему, ибо emo это val типа Resource, и если она(функция) не находит текстуру по заданному ресурсу, вызывает саму себя только с параметром emo.
И зачем делать так () => {} если можно так {}?
 
7,099
324
1,510
И зачем делать так () => {} если можно так {}?
чтобы было lazy. {} вычислится сразу. edited: неа, там же аргумент по имени, а не по значению

А зачем делать переполнение стака с emo?
 
Последнее редактирование:
1,111
47
420
чтобы было lazy. {} вычислится сразу.

А зачем делать переполнение стака с emo?
О интересно, буду знать.
Ну emo есть априори и тоже чтобы было lazy. Я ее загружу только тогда когда кто то укажет не верное имя.
 
7,099
324
1,510
Понятно. Но лучше тогда отделить эту логику так:
lazy val emo=loadTexture(<emoResource>)

override def bindTexture(resource: Resource): Unit = {
if (!resource.isTexture) throw new RuntimeException(s"$resource is not a texture")

textures.getOrElse(resource,()=>loadTexture(resource)).getOrElse(emo)
}).bindAsTexture()

}
loadTexture(resource: Resource)=...
 
1,111
47
420
Проверь метод getInput и расположение текстурки
Понимаешь какая штука. Будь там None и я бы сделал get была бы ошибка. А так я ставлю брэйк поинт внутри ImageIO#read и до туда просто не доходит.
 
7,099
324
1,510
Ну если туда не доходит, значит, лямбда не вызывается. А не вызывается она когда input==None, если бы было Some обязательно вызвалось бы
 
1,111
47
420
Ну если туда не доходит, значит, лямбда не вызывается. А не вызывается она когда input==None, если бы было Some обязательно вызвалось бы
Ага это было бы очевидно но в процессе дебагинга я узнал что оно туда блин входит и доходит до ImageIO#read. Дальще жмякую step into и поток виснет на загрузке нативной либы.
 
7,099
324
1,510
Наверное, проблема не в твоем коде.
Как вариант, попробуй грузить либу раньше
 

CumingSoon

Местный стендапер
1,634
12
269
Без оскорблений
> скала
> лямбды инлайнятся

только если на уровне jit'a и при должной доле везения, за бесплатными лямбдами welcome to Kotlin
В скале тоже есть inline. И на тех ф-ях, что выше, он висит.
 
808
3
124
В скале тоже есть inline. И на тех ф-ях, что выше, он висит.
А как это умудряется там работать на уровне хинтов компилятору?
1) Библиотека объявляет функцию как @inline
2) Программу, которая использует такую функцию, компилят с этой библиотекой
3) Библиотека обновляется и меняет содержимое той функции
4) Программу запускают с новой библиотекой не рекомпиля

(если пример с программой звучит абсурдно потому что вы рекомпилите программу под нужные версии библиотеки, то можете заменить программу на "библиотеку 2", тут точно хрен дождетесь рекомпила под нужную версию)

Есть хоть какие-то гарантии, как оно будет себя вести в итоге? В котлине inline - keyword компилятора, если заинлайнили - значит функция не обновится, точка. В скале рандомно?
 

CumingSoon

Местный стендапер
1,634
12
269
Честно говоря, я тебя вообще не понял.
Инлайнинг работает. Как - не знаю, нужно на гите искать сорсы.
Скорее всего, смотрится соурс скаловской либы. Если находится аннотация, то код попросту вставляется с опр. параметрами.
 
Последнее редактирование:
Сверху