Comstackción de código de representación en tiempo de ejecución

Me preguntaba si es posible escribir / modificar el código de representación cuando la aplicación de Android se está ejecutando. Mi objective principal es crear una aplicación donde los usuarios puedan aprender a trabajar con renderscript sin ningún conocimiento de Java. El diseño básico de la aplicación consistiría en una imagen de entrada y salida, con la posibilidad de entrada de código. La funcionalidad básica de esta aplicación ya está funcionando y esta es una imagen de la interfaz. Diseño de la aplicación

Sería útil probar el código de renderscript con comentarios directos de la aplicación.

Ya he investigado sobre el proceso de construcción y se me ocurrió la siguiente idea:

Un archivo de representación de “plantilla” básico, con las variables globales necesarias como asignaciones de entrada y salida.

Mi código Java crearía un objeto de secuencia de comandos de la clase Java generada y haría la inicialización básica de estas variables de secuencia de comandos globales. La función raíz de este archivo .rs de plantilla estaría vacía y el usuario debería poder implementarla en tiempo de ejecución.

Cuando el usuario escribe su código en la vista principal de la aplicación, el código se escribe en mi propio archivo .rs, que luego comstack el comstackdor llvm-rs-cc, invocado por la aplicación. El .bc generado se copiaría a la ubicación del archivo .bc original de la plantilla. Debido a que el único cambio de código ocurre dentro de la función raíz, no sería necesario realizar cambios en el código Java que lo rodea.

El problema que estoy teniendo en este momento es el hecho de que los archivos .bc están agrupados dentro del apk final dentro de la carpeta res / raw, que no es accesible por la aplicación. Por lo tanto, no es posible sobrescribir los archivos .bc antiguos con los archivos recién generados.

¿Hay alguna otra forma de comstackr código de representación en tiempo de ejecución?

Edición: La solución se puede encontrar en este enlace github . Para más detalles, verifique esta respuesta, lea el último comentario

Deberá alterar la clase de pegamento generada ( ScriptC_mono ) y su base ( ScriptC ) como mínimo.

El archivo .bc se lee y se transmite a los elementos internos de RenderScript. Por lo que puedo decir, eso se hace dentro de ScriptC.internalCreate() , que está conectado para leer un recurso en bruto. Lo necesitas para leer tu archivo desde una ubicación que controlas. Es posible que solo necesite modificar internalCreate() pero probablemente haya complicaciones que requieran una edición más amplia.

Una vez que implemente RuntimeScriptC , debe modificar ScriptC_mono para heredar de esa clase base en lugar de ScriptC .

Como notó, estará muy limitado en los cambios que puede hacer al código rs ya que no puede modificar la clase de pegamento en tiempo de ejecución. Por ejemplo, no se puede cambiar la firma de un núcleo. Sin embargo, podría llevar este truco un poco más lejos: si renuncia a la clase de pegamento, es posible realizar los cambios que desee.

Los núcleos se invocan en la clase de pegamento por índice en lugar de por nombre, y las comprobaciones de tipo / elemento se realizan dentro de la clase de pegamento. Por lo tanto, incluso si cambió la firma del kernel, siempre que conociera su índice y los tipos de asignaciones de entrada y salida, aún podría invocarlo utilizando forEach() directamente.

 public class ScriptC_mono extends ScriptC { //... public void forEach_root(Allocation ain, Allocation aout) { // check ain if (!ain.getType().getElement().isCompatible(__U8_4)) { throw new RSRuntimeException("Type mismatch with U8_4!"); } // check aout if (!aout.getType().getElement().isCompatible(__U8_4)) { throw new RSRuntimeException("Type mismatch with U8_4!"); // Verify dimensions Type tIn = ain.getType(); Type tOut = aout.getType(); if ((tIn.getCount() != tOut.getCount()) || (tIn.getX() != tOut.getX()) || (tIn.getY() != tOut.getY()) || (tIn.getZ() != tOut.getZ()) || (tIn.hasFaces() != tOut.hasFaces()) || (tIn.hasMipmaps() != tOut.hasMipmaps())) { throw new RSRuntimeException("Dimension mismatch between input and output parameters!"); } forEach(mExportForEachIdx_root, ain, aout, null); } }