Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Temas importantes
----------------------------------------
Páginas con recursos RPG Maker
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
Afiliados
Estadísticas
Tenemos 4068 miembros registrados.
El último usuario registrado es Schwarz54.

Nuestros miembros han publicado un total de 84121 mensajes en 11982 argumentos.

[Duda] ¿Para qué tanto revuelo con Fiber?

Ver el tema anterior Ver el tema siguiente Ir abajo

[Duda] ¿Para qué tanto revuelo con Fiber?

Mensaje por Wecoc el 2014-06-02, 16:54

No pude evitar hacer ciertas reflexiones sobre el funcionamiento de VX Ace, y concretamente su intérprete me ha despertado grandes dudas.
Éste tocho-post que pondré aquí explica mi lucha contra esa extraña clase (si no sabéis de RGSS/3 o Ruby no hace falta que continuéis...)

La principal diferencia entre los Interpreter (o Game_Interpreter) de XP y VX el de Ace es que Ace está basado en una especie de Thread recortado llamado Fiber, el cual podéis ver aquí:

Código:
class Fiber
  @@fs = []

  def initialize(&block)
    @k = lambda(&block)
    @prev = nil
  end

  def resume(*xs)
    raise FiberError, "dead fiber called" if @dead
    raise FiberError, "double resume" if @@fs[-1] == self
    @@fs.push(self)
    jump(xs)
  end

  def self.current
    @@fs.last
  end

  def self.yield(*xs)
    f = @@fs.pop
    f && f.send(:jump, xs)
  end

  def alive?
    !@dead
  end

  private
  def jump(xs)
    callcc do |k|
      destination = @k
      @k = k
      result = destination.call(*xs)
      @dead = true
      @@fs.pop
      @k.call result
    end
  end
end

class FiberError < StandardError
end


Pero por más que lo miro, no consigo entender las ventajas de esto. ¿Por qué se molestaron en reescribir gran parte del Interpreter y basarse en esto, si luego no hay diferencia visual ni de rendimiento respecto a los makers anteriores? No se pueden usar más llamadas a la vez sin crashear (100), no es más fácil llamarlo, modificarlo o entender su funcionamiento... NADA. Ni siquiera quedan más ordenados los comandos en el código, de hecho los veo peor, y eso que el Interpreter del XP por ejemplo ya era bastante mediocre en ciertos sentidos.

He estado intentando reescribir el Interpreter del XP para adaptarlo a Fiber (o más bien pasar lo del Ace al Interpreter del XP) para ver si encontraba alguna respuesta, y solo he encontrado dos bugs por culpa del @fiber.resume if @fiber dentro del update
Quitas esa línea del script, que es la principal vinculación con fiber, y todo va a la perfección.
La pones y te encuentras un bug con los Eventos Comunes; dejan de funcionar conjuntamente al evento si los llamas desde éste, y a consecuencia al acabar si pulsas enter, vuelve a iniciarse el evento en cuestión formándose un bucle infinito.
El segundo bug es que al llamar escena desde el evento (por ejemplo el comando Batalla, o también al teletransportar), si esa es la última acción del evento, éste se inactiva antes de lo previsto, su unlock va bastantes frames antes de la transición de pantalla (lo cual está mal).

Aquí el código:
Código:
#==============================================================================
#  ** XP Interpreter Edit for Fiber - Bug Reports
#==============================================================================

class Interpreter
 
  attr_reader  :map_id
  attr_reader  :event_id
  attr_reader  :fiber
 
  def clear
    @map_id = 0
    @event_id = 0
    @message_waiting = false
    @move_route_waiting = false
    @button_input_variable_id = 0
    @wait_count = 0
    @child_interpreter = nil
    @list = nil
    @index = 0
    @branch = {}
    @fiber = nil
  end

  def setup(list, event_id)
    clear
    @map_id = $game_map.map_id
    @event_id = event_id
    @list = list
    @index = 0
    @branch.clear
    create_fiber
  end
 
  def create_fiber
    @fiber = Fiber.new { run } if @list
  end
   
  def run
    loop do
      if @list == nil
        @fiber = nil
        break
      else
        Fiber.yield while @message_waiting
        Fiber.yield while @wait_count > 0
        execute_command
        @index += 1
      end
    end
  end

  def running?
    @fiber != nil
  end
 
  def update
    @loop_count = 0
    # @fiber.resume if @fiber
    loop do
      @loop_count += 1
      if @loop_count > 100
        Graphics.update
        @loop_count = 0
      end
      if $game_map.map_id != @map_id
        @event_id = 0
      end
      if @child_interpreter != nil
        @child_interpreter.update
        unless @child_interpreter.running?
          @child_interpreter = nil
        end
        if @child_interpreter != nil
          return
        end
      end
      if @message_waiting
        return
      end
      if @move_route_waiting
        if $game_player.move_route_forcing
          return
        end
        for event in $game_map.events.values
          if event.move_route_forcing
            return
          end
        end
        @move_route_waiting = false
      end
      if @button_input_variable_id > 0
        input_button
        return
      end
      if @wait_count > 0
        @wait_count -= 1
        return
      end
      if $game_temp.forcing_battler != nil
        return
      end
      if $game_temp.battle_calling or
        $game_temp.shop_calling or
        $game_temp.name_calling or
        $game_temp.menu_calling or
        $game_temp.save_calling or
        $game_temp.gameover
        return
      end
      if @list == nil
        if @main
          setup_starting_event
        end
        if @list == nil
          return
        end
      end
      if execute_command == false
        return
      end
      @index += 1
    end
  end
 
  def execute_command
    if @index >= @list.size - 1
      command_end
      return true
    end
    command = @list[@index]
    @parameters = command.parameters
    @indent = command.indent
    method_name = "command_#{command.code}"
    send(method_name) if respond_to?(method_name)
  end
 
  def command_end
    Fiber.yield while @message_waiting
    Fiber.yield while @wait_count > 0
    @list = nil
    @fiber = nil
    if @main and @event_id > 0
      $game_map.events[@event_id].unlock
    end
  end
 
  def command_108 ## Comment
    @comments = [@parameters[0]]
    while @list[@index + 1].code == 408
      @index += 1
      @comments.push(@list[@index].parameters[0])
    end
  end
end


Otra duda es, ¿Por qué Fiber y no Thread?
En fin, en resumen; ¿Por qué VX Ace hizo eso? xD
avatar
Wecoc
Administrador
Administrador



Créditos 9129

Gracias : 471

Volver arriba Ir abajo

Re: [Duda] ¿Para qué tanto revuelo con Fiber?

Mensaje por orochii el 2014-06-03, 19:21

Lo que he visto es ésto. El RPG Maker, cualquiera que sea, está estropeado y no sirve usar ni Fiber ni Thread, por el simple y llano hecho de que el estúpido Graphics detiene absoluta y completamente TODO el maldito intérprete Ruby xD. Y lo hace esperar por un "delta time" (para ajustar el framerate).

Hay otra cosa que leí ayer, que sí podría ayudarle al RPG Maker y que en BUENA teoría no debería ser tan difícil :V. Bueno, sí, pero no es tan imposible o no es algo sólo digno de scripters de Chaos Project xD.

Es algo sobre reescribir los métodos de Bitmap. Los más lentos en el maker xD. Implementar el clear, blt y todo eso de dibujado en C++. Leí de un tipo que lo está haciendo. Lo que no entiendo o no me convence es que DICEN el DLL que está desarrollando será comercial :V. Y pos, bueh, ya saben, prefiero si dejan las cosas libres por ahí a que floten en el viento. =D. ¿Quién no? xD. Supuestamente en sus pruebas de estrés se ha ganado FPS respecto a la implementación original. Pero claro, es tan secreto y desconocido que por ahora esas palabras valen igual a nada xD.
avatar
orochii
Caballero Shiro
Caballero Shiro

0/3

Créditos 6359

Gracias : 325

http://ragnarokrproject.com/

Volver arriba Ir abajo

Re: [Duda] ¿Para qué tanto revuelo con Fiber?

Mensaje por Wecoc el 2014-06-03, 22:30

Orochii, eso no responde mi duda xD Sabía que Graphics paraba los Thread, aunque no sé si a todos los $SAFE o como se llame eso, pero sigo sin ver ni por qué Fiber y no el intérprete normal basado puramente en @list, ni por qué no usar Thread. Quizá la cagaran como con otras cuestiones y en vez de pasar el XP a Fiber habría que pasar el VX Ace a no-Fiber (?) xDD

Me sorprende eso de reescribir el Bitmap en dll, más que nada porque estaba bastante seguro de que eso ya existía (yo conocía ésto del Author's Notes, quizá no lo sea, pero creía que era justamente lo que has dicho)

Soy consciente de que cuando se crearon XP y VX no existía Fiber, puesto que es un script que se creó con una versión de Ruby posterior que de las tres solo el Ace tiene (es por ello que XP y VX requieren el script Fiber que puse arriba para usarlo y el Ace no). Eso me hace plantearme una posible pataleta en plan "Lo uso porque puedo" xD pero más allá como dije no veo ventajas en ninguna parte.

Spoiler:
PD.- Al pesado de los negativos, solo estoy haciendo una duda inofensiva. Si no te gusta, rebota rebota y en tu culo explota.
avatar
Wecoc
Administrador
Administrador



Créditos 9129

Gracias : 471

Volver arriba Ir abajo

Re: [Duda] ¿Para qué tanto revuelo con Fiber?

Mensaje por Mukadelheid el 2014-06-04, 21:10

Los "Fiber´s" son primitivas para la implementación de concurrencias cooperativas livianas en Ruby.
Fundamentalmente se trata de un medio para crear bloques de código que pueden ser pausados y reanudados, al igual que los "threads".
La principal diferencia es que "ellas" nunca serán adelantadas o precedidas y la programación debe ser hecha por el programador y no por la "Maquina Virtual".

A diferencia de otros modelos de concurrencias livianas que no "stackean", cada "fiber" viene con un pequeño "stack" de 4KB.
Esto permite que "fiber" sea pausada desde llamadas de función muy profundas anidadas dentro del bloque de "fiber".

Cuando un "fiber" es creado, no se ejecutara automáticamente. Mas bien, debe ser "explicitamente" solicitado, utilizando "Fiber#resume method"
El código ejecutándose dentro de "Fiber" puede ceder el control a través de una llamada "Fiber.yield" en cuyo caso le remite el control a quien lo llame.(Al que ejecute "Fiber#resume").
Tras ceder o terminar, "Fiber" regresa el valor de la ultima expresión ejecutada.



Última edición por Mukadelheid el 2014-06-04, 21:34, editado 1 vez (Razón : íó+n , me comí varias letras)
avatar
Mukadelheid
Principiante
Principiante

0/3

Créditos 334

Gracias : 28

Volver arriba Ir abajo

Re: [Duda] ¿Para qué tanto revuelo con Fiber?

Mensaje por orochii el 2014-06-05, 03:53

Mmmm interesante. Entonces el Fiber es como el tratar de no reinventar la rueda a la hora de implementar el intérprete, ¿no? Porque el asunto del control de los intérpretes y demás antes se hacía de cero.

Respecto al módulo ese de transiciones... vaya. Está genial :D!. Algo así me refería, pero hacerlo con blt, clear y los demás métodos de Bitmap. Que no sé, algo me dice que Bitmap está escrito en Ruby xD (o eso parece :VVV :modo de decir caca:).

...Yo debería experimentar con eso de hacer cosas en bitmaps por C++. Pero me da miedo :'D (?).
avatar
orochii
Caballero Shiro
Caballero Shiro

0/3

Créditos 6359

Gracias : 325

http://ragnarokrproject.com/

Volver arriba Ir abajo

Re: [Duda] ¿Para qué tanto revuelo con Fiber?

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.