π
<-

LUA OnCalc

Pour TI-Nspire OS 3.0 ou ultérieur.

LUA OnCalc

Unread postby Dyar » 03 Sep 2011, 10:26

Je vous ai déjà parlé de mon projet LUA OnCalc sur TIbank en début d'été.
C'est un programme qui utilise la fonction loadstring de la bibliothèque standard lua pour exécuter un programme lua édité sur la calculatrice.
J'ai complètement réécrit le programme, pour de nombreuses améliorations...
Maintenant chaque nouvelle page contenant un exécuteur va se donner un identifiant différent, et chargera l'ensemble du programme contenu dans une seule variable lua_prgm_[id], ce chargement se faisant à la demande de l'utilisateur, par la modification du contenu de la variable lua_reload_[id].
La compilation et l’exécution du contenu de cette variable est sécurisé, ainsi que l'appel à toutes les fonctions événement, ce qui fait que toute erreur sera gérée et affiché par l’exécuteur et non par l’interpréteur, ce qui aurait pour effet de bloquer l’exécuteur, et donc au mieux de recharger complètement le document, au pire de devoir remettre l’exécuteur sur la calculatrice à partir de l'ordinateur, ce qui est un peu dommage vu l'objectif de ce programme !

Je fais en même temps un éditeur sur la calculatrice, qui fonctionnera en parallèle de ce programme.

Donc tout ça marche très bien, sauf au moment où le document est rechargé... La fonction on.restore n'est pas appelée, les id sont donc remis à jour et le programme utilisateur n'est plus exécuté ...

Voici donc mon code, si vous avez une idée de pourquoi on.restore n'est pas appelée ...
Mes tests on montré que on.save était bien appelée et que on.restore était correctement définie au moment de l'appel à on.create, ce qui n’était pas forcement évident vu les modifications à la table "on."

Si vous avez des questions ou remarques sur l'optimisation de ce programme, n'hésitez pas !

Code: Select all
EX_s = {id = nil, Loaded = false, Error = nil, isEditor = false, on={}}   -- table for global variables


-- error

function EX_s:err(txt)
   EX_s.Error = txt
   platform.window:invalidate()
end

-- sucurised exec

function EX_s:exec(f, arg)
   local s, r

   if not f then return nil end

   s, r = pcall(f, arg)

   if not s then
      EX_s:err("(E) ".. r)
   else
      return r
   end
end

-- reload ext prgm

function EX_s:reload()
   
   if EX_s.isEditor then   -- clean errors
      EX_s.Error = nil
      EX_s.isEditor = false
      EX_s.editor:setText("")
      EX_s.editor:move(0,0)
      EX_s.editor:resize(1,1)
   end
   
   EX_s.Loaded = false
   var.store("lua_reload_"..EX_s.id, 0)
   on = {}
   
   local prgm = var.recall("lua_prgm_"..EX_s.id)   --get prgm txt
   
   if not prgm then
      EX_s:err("Error reading lua_prgm_"..EX_s.id)
   elseif type(prgm) ~= "string" then
      EX_s:err("lua_prgm_"..EX_s.id .. "should be a string")
   else
      local cmp, err = loadstring(prgm)      -- compile prgm
      if not cmp then
         EX_s:err("(C) " .. err)
      else
         local s,r = pcall(cmp)            -- exec prgm
         if not s then
            EX_s:err("(CE) " .. r)
         else
            for i,f in pairs(on) do         -- securize "on." functions, the olny who can be called externally
               EX_s.on[i] = f
               on[i] = loadstring("return function(arg) return EX_s:exec(EX_s.on["..i.."], arg) end")()
            end
            EX_s.Loaded = true
         end
      end
   end
   
   EX_s:reinit()
   platform.window:invalidate()
   
end

-- reinitialisation of events endlers

function EX_s:reinit()

   function on.paint(gc)
   
      if EX_s.Error then      -- error windows
      
         gc:setColorRGB(255,0,0)
         gc:drawString("Error", platform.window:width()/2-gc:getStringWidth("Error")/2, 0, "top")
         gc:setColorRGB(0,0,0)   
         if not EX_s.isEditor then
            EX_s.editor:move(10,20)
            EX_s.editor:resize(platform.window:width()-20, platform.window:height()-30)
            EX_s.editor:setText(EX_s.Error)
            EX_s.isEditor=true
         end
         
      elseif not EX_s.Loaded then   --idle window
      
         gc:drawString("Exec ID:"..EX_s.id, platform.window:width()/2-gc:getStringWidth("Exec ID:"..EX_s.id)/2, platform.window:height()/4, "top")
         
      else
         EX_s:exec(EX_s.on.paint, gc)
      end
   end
   
   function on.varChange(varlist)
         -- reload event
      if not var.recallstr("lua_reload_"..EX_s.id) then return -3 -- never delete this var
      elseif var.recall("lua_reload_"..EX_s.id)~=0 then
         EX_s:reload()
         return 0
      elseif Ex_s.Loaded then
         return EX_s:exec(EX_s.on.varChange, var)
      end
      return 0
   end
   
   function on.save()
      local ret = {}
      ret.EX_s = EX_s
      if EX_s.Loaded then
         ret.u_sv = EX_s:exec(EX_s.on.save)
      end
      return ret
   end
   
   function on.restore(data)
      EX_s = data.EX_s
      if ret.u_sv then
         EX_s:exec(EX_s.on.restore, ret.u_sv)
      end
   end
   
   function on.create()
      if not EX_s.id then
      
            -- initialisation

         -- look for curent id

         EX_s.id = var.recall("lua_cur_id")
         if not EX_s.id then                        --  create it
            EX_s.id = 0
         else
            EX_s.id = EX_s.id+1                     -- or update it
         end
         math.eval("Unlock lua_cur_id")
         var.store("lua_cur_id",EX_s.id)               -- and store it
         math.eval("Lock lua_cur_id")

         -- setting programme update information var

         if not var.recallstr("lua_reload_"..EX_s.id) then
            var.store("lua_reload_"..EX_s.id, 0)
         elseif var.recall("lua_reload_"..EX_s.id)~=0 then
            EX_s:reload()                     -- if the prgm already exist, then try to load it
         end
         var.monitor("lua_reload_"..EX_s.id)

         -- cration of D2 editor for error informations :
         if not EX_s.editor then
            EX_s.editor = D2Editor.newRichText()
         end
         EX_s.editor:setReadOnly(true)
      
      end
      
      EX_s:exec(EX_s.on.create)
      
   end
   
end

EX_s:reinit()
User avatar
Dyar
Niveau 4: MC (Membre Confirmé)
Niveau 4: MC (Membre Confirmé)
Level up: 40%
 
Posts: 22
Joined: 24 Feb 2010, 00:00
Location: Clermont Ferrand
Gender: Male
Calculator(s):
MyCalcs profile
Class: MP*

Re: LUA OnCalc

Unread postby Dyar » 03 Sep 2011, 11:17

Avec un nombre à la place de mes tables et sortie de on.save ça a l'air de marcher ... mais sur un exemple plus simple j'avais reussi à le faire marcher avec des tables ...
[edit] en fait non ... Qulque soit le type de sortie de on.save, on.restore n'est pas appelé. Etrange !
Sinon il faut que je refasse le on.create qui ne sera plus adapté quand ça marchera.
User avatar
Dyar
Niveau 4: MC (Membre Confirmé)
Niveau 4: MC (Membre Confirmé)
Level up: 40%
 
Posts: 22
Joined: 24 Feb 2010, 00:00
Location: Clermont Ferrand
Gender: Male
Calculator(s):
MyCalcs profile
Class: MP*

Re: LUA OnCalc

Unread postby Dyar » 03 Sep 2011, 18:27

Bon,après avoir passé la journée sur ce problème, je pense comprendre un peu mieux le fonctionnement de on.restore ...

Ce qui va suivre n'est pas du tout évident, et peut servir à d'autres, il faudrait peut être en faire mention sur la doc ...

Déjà, les erreurs ne sont pas détectées à l'erreur dans cette fonction, et la fonction var.store n'a pas d'effet.
Vu que c'était mes deux méthodes de débogage, c'est pour cela que je pensais que la fonction n'était jamais appelée.

En réalité, elle n'était pas appelée que lorsque on.save retourne un résultat non valide.
Ceci est mon cas pour deux raison : ma variable de sauvegarde contenait un D2Editor, ce qui apparemment n'est pas permis. En fait je m'en doutais, vu que cette variable ne fait que "pointer" vers l’éditeur, qui est une structure interne.
Deuxième problème, cette variable contenait une table de fonctions, ce qui est aussi interdit !

J'ai essayé d'apporter une solution en transformant ces fonctions en chaînes de caractère à l'aide de string.dump, mais ceci provoque une erreur au chargement du classeur :"An error was found in the format of this document" (bug exploitable ??) sûrement lié au fait que le contenu de ces chaînes est binaire ...
Enfin, je suis en train de réaliser qu'il faut de toute façon que je sauvegarde le contenu du text utilisateur, qui doit être réexecuté à ce moment ... Ceci pourrait apporter une solution !
User avatar
Dyar
Niveau 4: MC (Membre Confirmé)
Niveau 4: MC (Membre Confirmé)
Level up: 40%
 
Posts: 22
Joined: 24 Feb 2010, 00:00
Location: Clermont Ferrand
Gender: Male
Calculator(s):
MyCalcs profile
Class: MP*

Re: LUA OnCalc

Unread postby Adriweb » 03 Sep 2011, 19:06

Post très intéressant, j'ai voté 5 étoiles.

Je vais étudier ca de plus près, en effet ca a l'air intéressant tout ca....

!call Levak aussi, il sera intéressé....

MyCalcs: Help the community's calculator documentations by filling out your calculators info!
MyCalcs: Aidez la communauté à documenter les calculatrices en donnant des infos sur vos calculatrices !
Inspired-Lua.org: All about TI-Nspire Lua programming (tutorials, wiki/docs...)
My calculator programs
Mes programmes pour calculatrices
User avatar
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 79.9%
 
Posts: 14837
Images: 1131
Joined: 01 Jun 2007, 00:00
Location: France
Gender: Male
Calculator(s):
MyCalcs profile
Twitter: adriweb
GitHub: adriweb

Re: LUA OnCalc

Unread postby Levak » 03 Sep 2011, 19:19

Si ça peut t'aider au raisonnement, on.restore() sauve ta variable en clair dans le document XML (visible avec un dump lors du copier/collé). Il utilise donc une chaine de caractère, mais peut être bien le format standard tu TI-Basic (nombres, string, liste polymorphe, matrices, programmes, fonctions).

Récupérer le source d'une fonction est "possible". string.dump() retourne une chaine qui est en fait coupée par print() car contenant un \0. Jim Bauwens bossait dessus, je ne sais pas où il en est.
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

Re: LUA OnCalc

Unread postby Adriweb » 03 Sep 2011, 19:30

Levak wrote:Si ça peut t'aider au raisonnement, on.restore() sauve ta variable en clair dans le document XML (visible avec un dump lors du copier/collé)

Pour info, il suffit de télécharger un clipboard viewer, assez basique même, et le contenu de l'activité copié est enregistré en non-encrypté, donc visible par le logiciel.

Levak wrote:Récupérer le source d'une fonction est "possible". string.dump() retourne une chaine qui est en fait coupée par print() car contenant un \0. Jim Bauwens bossait dessus, je ne sais pas où il en est.

Sur ce point la, j'ai aussi pas mal bossé dessus, et ce qu'il faut préciser c'est que l'on a acces uniquement aux fonctions définies dans le script Lua lui même. Il est impossible de retrouver le code des hooks en C derriere l'interpréteur Nspire Lua.

MyCalcs: Help the community's calculator documentations by filling out your calculators info!
MyCalcs: Aidez la communauté à documenter les calculatrices en donnant des infos sur vos calculatrices !
Inspired-Lua.org: All about TI-Nspire Lua programming (tutorials, wiki/docs...)
My calculator programs
Mes programmes pour calculatrices
User avatar
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 79.9%
 
Posts: 14837
Images: 1131
Joined: 01 Jun 2007, 00:00
Location: France
Gender: Male
Calculator(s):
MyCalcs profile
Twitter: adriweb
GitHub: adriweb

Re: LUA OnCalc

Unread postby Levak » 03 Sep 2011, 19:46

Adriweb wrote:
Levak wrote:Si ça peut t'aider au raisonnement, on.restore() sauve ta variable en clair dans le document XML (visible avec un dump lors du copier/collé)

Pour info, il suffit de télécharger un clipboard viewer, assez basique même, et le contenu de l'activité copié est enregistré en non-encrypté, donc visible par le logiciel.



Ou de s'en faire un :D

Le mien est en C# et je n'arrive pas à réécrire dessus à cause d'un mauvais header.
Logiquement en Java ça serait très facilement faisable en utilisant les même routines java que TI Nspire Computer Software
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

Re: LUA OnCalc

Unread postby Dyar » 04 Sep 2011, 08:26

Si ça peut t'aider au raisonnement, on.restore() sauve ta variable en clair dans le document XML (visible avec un dump lors du copier/collé). Il utilise donc une chaine de caractère, mais peut être bien le format standard tu TI-Basic (nombres, string, liste polymorphe, matrices, programmes, fonctions).


C'est ce que je me disais aussi, mais n’ayant pas encore essayé de visionner le contenu du clipboard, je n'avais pas moyen de confirmer.

Récupérer le source d'une fonction est "possible". string.dump() retourne une chaine qui est en fait coupée par print() car contenant un \0. Jim Bauwens bossait dessus, je ne sais pas où il en est.


Je n'avais pas regardé avec un print(), mais ça fait le même effet avec un var.store(). Et ça doit être ça aussi qui fait planter le logiciel nspire à l'ouverture d'un classeur dans lequel a été sauvegardé une chaîne contenant le code d'une fonction récupéré par string.dump()... Je n'ai pas testé sur calculatrice. Mais je pense que ce code n'est pas exploitable, dans la doc on parle de code binaire.

Sinon pour mon programme il me reste un dernier problème de "C stack overflow", je cherche d'où ça vient !
User avatar
Dyar
Niveau 4: MC (Membre Confirmé)
Niveau 4: MC (Membre Confirmé)
Level up: 40%
 
Posts: 22
Joined: 24 Feb 2010, 00:00
Location: Clermont Ferrand
Gender: Male
Calculator(s):
MyCalcs profile
Class: MP*

Re: LUA OnCalc

Unread postby Chockosta » 04 Sep 2011, 10:26

Pour le "C stack overflow", si je ne m'abuse, c'est qu'il n'y a plus assez de place dans la pile...
Et comme en lua, tu choisis pas ce que tu mets dans la pile et dans le tas, va falloir trouver un moyen d'économiser la mémoire.
User avatar
ChockostaPremium
Niveau 10: GR (Guide de Référence)
Niveau 10: GR (Guide de Référence)
Level up: 2.2%
 
Posts: 213
Joined: 24 Feb 2011, 00:00
Gender: Male
Calculator(s):
MyCalcs profile
Class: Math sup

Re: LUA OnCalc

Unread postby Levak » 04 Sep 2011, 10:26

Un programme récursif ?
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

Next

Return to Nspire-Lua

Who is online

Users browsing this forum: ClaudeBot [spider] and 1 guest

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1308 utilisateurs:
>1266 invités
>35 membres
>7 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)