Trans ignore some classes methods (HTML 5)
Monkey Forums/Monkey Bug Reports/Trans ignore some classes methods (HTML 5)
| ||
Hi, Mark i am calling out for your help. Ive just discovered a major flaw in my project. My project is rather big but this shouldn't cause this to be honest. It seem to be a Trans bug to me.. at first sight or is there something i am not aware of ? I have 4 classes that inherit from a base class. While testing on html 5... 2 of theses classes do not enter in their overrided methods, the base methods was used instead. I didn't understand why... but it worked for XNA platform. While checking for the XNA source code ive discovered that everything was normal while debugging.. the correct methods are executed from the parent class but in html 5... thoses classes was generated but the methods was not. Only 2 of thoses classes had their methods generated which probably explain why the base class is used instead. The classes methods definitions wasn't there... i posted the whole code in monkey and the code that was generated to help out. I would be glad to discover what happen really. ******* Here the both classes that working ******* DoConnectionTask (Monkey code) DoConnectionTask (HTML 5 code) DoAuthenticationTask (Monkey code) DoAuthenticationTask (HTML 5 code) ******* Here the both classes that NOT working, adding new ones also doesn't work ******* DoHandleUpdateTestTask (Monkey code) DoHandleUpdateTestTask (HTML 5 code) c_DoGetMenuPlayerDataTask (Monkey code) c_DoGetMenuPlayerDataTask (HTML 5 code) I was looking for something like... but it was not found. c_DoGetMenuPlayerDataTask.prototype.p_StartCondition=function(){ ... } Also apply to DoHandleUpdateTestTask... not found either c_DoHandleUpdateTestTask.prototype.p_StartCondition=function(){ ... } Do you have any ideas what could cause this ? I am using JungleIDE but i don't think at all this could be the cause.. but its worth mentionning. It is possible also that this is due to the imports ? i doubt since the two classes that are working are on the same level. I am using monkey69. Thanks a lots for your help. |
| ||
I think its because of the 'unreachable code' algorithm cutting out the code from being translated. If you include the code with reflection the code it will be added. |
| ||
How do i do that ? I need reflecrion filter for theses classes? |
| ||
Damn. I just tested your solution and it work perfectly now... strange. This can lead to lots of confusion is there a way to determine when exactly we need to put our classes in the reflection filter ? or do you suggest to pass all the classes to the filter ? i wanted to avoid this because of the overhead this can cause.. it seem like that everythink that require some class extends need it. Anyway thanks a lots for your help really appreciated! |
| ||
Its trial and error really, as this is a bug. Reflecting every class would create loads of code and slow down compilation. Dunno how it effects game speed. All this could be solved by turning off the algorithm that excludes 'unreachable code' |
| ||
Mark, what your opinion on this ? |
| ||
Can you post something I can actually run - ie: reduce it down to a minimal example? If it's something to do with dead code elimination, it's probably to do with how objects are created and/or how methods are called, and you haven't shown any of that. But if it's working on XNA but not html5, that's esp. weird as the code elimination is target-independent. |
| ||
I made one but i deleted it.. since the sample was fully working without problems which is kind of odd. But i had put the tasks in the same main class module so maybe that explain why it was working. I will try to get something for you tomorrow. What slenkar suggested worked so this have to do with reflection or something... I am 100% sure that its working on XNA but not HTML 5. Here i posted the complete class of tasks handling that show how methods are called but i doubt it will help. Basically i use RegisterTask to register a task (class based on Task object) this add the task to an internal list. Then i call methods StartCondition etc.. with IF statements. The idea of a Task is to be run using a start condition, end condition and with support of callbacks for post-operations. This include Task, TasksHandler and other dependent classes. UpdateTasks:Void is what update the tasks... this is called in the OnUpdate method normally. There also a RenderTasks for tasks associated to rendering. Strict Import mojo 'summary: Gestionnaire de tâches. Class TasksHandler Private Field tasksList:IntMap<Task> Public 'summary: Créer une gestionnaire de tâches. Method New() tasksList = New IntMap<Task>() End 'summary: Enregistrer une tâche dans le gestionnaire. Method RegisterTask:Void(task:Task) If Not tasksList.Contains(task.taskId) tasksList.Add(task.taskId, task) End If End 'summary: Terminer la tâche (avec erreur) à partir de son identifiant de la liste de tâche. Method TerminateTask:Void(taskId:Int, hasErrors:Bool, errorCode:Int, reason:String) If Self.tasksList.Contains(taskId) Then Local t:Task = Self.tasksList.Get(taskId) t.Terminate(hasErrors, errorCode, reason) Else Error("The task with ID " + taskId + " are not active in the task list!") End If End 'summary: Terminer la tâche (sans erreur) à partir de son identifiant de la liste de tâche. Method TerminateTask:Void(taskId:Int) If Self.tasksList.Contains(taskId) Then Local t:Task = Self.tasksList.Get(taskId) t.Terminate(False, -1, "Task terminated normally.") Else Error("The task with ID " + taskId + " are not active in the task list!") End If End 'summary: Obtenir la tâche à partir de son identifiant. Method GetTask:Task(taskId:Int) Return Self.tasksList.Get(taskId) End 'summary: Déterminer si la tâche est toujours active. Method TaskIsActive:Bool(taskId:Int) Local result:Bool = False If Self.tasksList.Contains(taskId) Then result = Self.tasksList.Get(taskId).IsStillActive() End If Return result End 'summary: Obtenir le nombre de tâches enregistrées. Method GetNbOfTasks:Int() Return tasksList.Count() End 'summary: Mettre à jour les tâches. Method UpdateTasks:Void() For Local n:= EachIn tasksList Local t:Task = n.Value Local taskSettings:TaskSettings = t.settings ' Vérifier si la condition de fin a été remplie et marquer la tâche comme étant complété ' si c'est le cas. If t.CompleteCondition() Then ' Marquer la tâche comme complété. t.isFinished = True ElseIf t.ErrorCondition() Then ' Vérifier si la condition d'erreur est remplie. ' Marquer la tâche comme complété. t.isFinished = True ' Marquer la tâche comme étant en erreur. If Not t.hasErrors Then t.hasErrors = True End If ' Déterminer si la tâche est terminée. Si OUI alors éxécuter les événements de fin de tâche. If t.isFinished Then ' Éxécuter l'événement de fin de tâche. If Not t.hasErrors t.TaskCompleted() Else t.TaskError(t.terminateReason, t.errorCode) End If ' Retirer la tâche de la liste de tâches. Self.tasksList.Remove(t.taskId) Else ' Déterminer si la condition de départ est remplie ainsi que le délai de démarrage requis pour ' démarrer la tâche sinon passer à la suivante. Local startDelayPassed:Bool = t.startedTime + taskSettings.startDelay <= Millisecs() If t.StartCondition() And startDelayPassed Then t.isStarted = True End ' Éxécuter les opérations de la tâches si elle est démarré. If t.isStarted Then ' Vérifier s'il faut que la condition de départ soit vérifier au début de l'éxécution. Local canProceedExecution:Bool = True If t.settings.checkStartConditionEachTime Then canProceedExecution = t.StartCondition() End If If canProceedExecution Then ' S'il s'agit de la première éxécution, on détermine le temps actuel de l'éxécution. If t.lastExecutionTime = 0 Then t.lastExecutionTime = Millisecs() End If ' Déterminer si on doit vérifier la condition de départ avant l'éxécution. ' Si OUI alors on vérifie la condition de départ et si on a dépassé le délai d'éxécution requis pour ' déterminé si on peut démarré l'éxécution de la tâche sinon on fait juste vérifié si on a dépassé ' le délai d'éxécution requis pour démarrer l'éxécution de la tâche. Local canStartExecution:Bool = True Local executionDelayPassed:Bool = t.lastExecutionTime + taskSettings.executionDelay <= Millisecs() If taskSettings.checkStartConditionEachTime = True Then canStartExecution = t.StartCondition() And executionDelayPassed And t.nbOfExecution < t.settings.maxNbOfExecution Else canStartExecution = executionDelayPassed And t.nbOfExecution < t.settings.maxNbOfExecution End If ' Déterminer si ont peut démarré l'éxécution de la tâche. If canStartExecution Then ' Déterminer le dernier temps d'éxécution. t.lastExecutionTime = Millisecs() ' Éxécuter la tâche. t.Execute() ' Incrémenté le nombre d'éxécution. t.nbOfExecution = t.nbOfExecution + 1 End If End If End If End If Next End 'summary: Afficher le rendu des tâches démarrées. Method RenderTasks:Void() For Local n:= EachIn tasksList Local t:Task = n.Value If t.isStarted Then t.Render() End If Next End 'summary: Effacer les tâches en cours. Method ClearTasks:Void() tasksList.Clear() End End 'summary: Représente les paramètres pour une tâche. Class TaskSettings Private Field maxNbOfExecution:Int Field checkStartConditionEachTime:Bool Field startDelay:Int Field executionDelay:Int Field expirationDelay:Int Public Const ONE_TIME_EXECUTION:Int = 1 Const NO_DELAY:Int = 0 Const DEFAULT_EXPIRATION_DELAY:Int = 15 Const NO_EXPIRATION:Int = -1 Method New() Self.maxNbOfExecution = TaskSettings.ONE_TIME_EXECUTION Self.startDelay = TaskSettings.NO_DELAY Self.executionDelay = TaskSettings.NO_DELAY Self.checkStartConditionEachTime = False Self.expirationDelay = DEFAULT_EXPIRATION_DELAY End Method New(maxNbOfExecution:Int) Self.maxNbOfExecution = maxNbOfExecution Self.startDelay = TaskSettings.NO_DELAY Self.executionDelay = TaskSettings.NO_DELAY Self.checkStartConditionEachTime = False Self.expirationDelay = DEFAULT_EXPIRATION_DELAY End Method New(maxNbOfExecution:Int, startDelay:Int) Self.maxNbOfExecution = maxNbOfExecution Self.startDelay = startDelay Self.executionDelay = TaskSettings.NO_DELAY Self.checkStartConditionEachTime = False Self.expirationDelay = DEFAULT_EXPIRATION_DELAY End Method New(maxNbOfExecution:Int, startDelay:Int, executionDelay:Int) Self.maxNbOfExecution = maxNbOfExecution Self.startDelay = startDelay Self.executionDelay = executionDelay Self.checkStartConditionEachTime = False Self.expirationDelay = DEFAULT_EXPIRATION_DELAY End Method New(maxNbOfExecution:Int, startDelay:Int, executionDelay:Int, checkStartConditionEachTime:Bool) Self.maxNbOfExecution = maxNbOfExecution Self.startDelay = startDelay Self.executionDelay = executionDelay Self.checkStartConditionEachTime = checkStartConditionEachTime Self.expirationDelay = DEFAULT_EXPIRATION_DELAY End Method New(maxNbOfExecution:Int, startDelay:Int, executionDelay:Int, checkStartConditionEachTime:Bool, expirationDelay:Int) Self.maxNbOfExecution = maxNbOfExecution Self.startDelay = startDelay Self.executionDelay = executionDelay Self.checkStartConditionEachTime = checkStartConditionEachTime Self.expirationDelay = expirationDelay End End 'summary: Représente une tâche. Class Task Private Field taskId:Int Field settings:TaskSettings Field nbOfExecution:Int Field isFinished:Bool Field isStarted:Bool Field startedTime:Int Field lastExecutionTime:Int Field hasErrors:Bool Field terminateReason:String Field errorCode:Int Public 'summary: Créer une tâche. Method New(taskId:Int, settings:TaskSettings) Self.startedTime = Millisecs() Self.taskId = taskId Self.settings = settings Self.isFinished = False End 'summary: Obtenir le code d'erreur. (Optionnel) Method ErrorCode:Int() Property Final Return Self.errorCode End 'summary: Déterminer si des erreurs ce sont produites lors de l'éxécution de la tâche. Method HasErrors:Bool() Property Final Return Self.hasErrors End 'summary: Obtenir la raison de la terminaison de la tâche. (Optionnel) Method TerminateReason:String() Property Final Return Self.terminateReason End 'summary: Obtenir l'identifiant de la tâche. Method Id:Int() Property Final Return Self.taskId End 'summary: Obtenir les paramètres de la tâche. Method Settings:TaskSettings() Property Final Return Self.settings End 'summary: Obtenir le temps de démarrage de la tâche. Method StartedTime:Int() Property Final Return Self.startedTime End 'summary: Déterminer si la tâche est démarré. Method IsStarted:Int() Property Final Return Self.isStarted End 'summary: Déterminer si la tâche est toujours active. Method IsStillActive:Bool() Property Final Return Self.isStarted And Not Self.isFinished End 'summary: Déterminer si la tâche est expiré. Method HasExpired:Bool() Property Final Return (Self.settings.expirationDelay <> TaskSettings.NO_EXPIRATION) And (Self.StartedTime() + (Self.settings.expirationDelay * 1000)) <= Millisecs() End 'summary: Obtenir le nombre d'éxécution effectué. Method CurrentNbOfExecution:Int() Property Final Return Self.nbOfExecution End 'summary: Condition à respecter pour démarrer la tâche. Method StartCondition:Bool() Print("Super() executed!" + Id()) Return True End 'summary: Condition qui détermine quand la tâche est terminée. 'IMPORTANT: Il est possible d'utiliser Super.CompleteCondition() dans la méthode correspondante de la classe qui hérite de 'Tasks 'pour inclure la condition d'un certain nombre maximum d'éxécution possible avant la terminaison de la tâche. '(Si toutefois celle-ci est définie dans la configuration de la tâche) Method CompleteCondition:Bool() Local endTask:Bool = False If Self.settings.maxNbOfExecution <> - 1 Then endTask = nbOfExecution >= Self.settings.maxNbOfExecution EndIf Return endTask End 'summary: Condition à respecter pour considéré la tâche comme étant en erreur. 'IMPORTANT: Il est possible d'utiliser Super.ErrorCondition() dans la méthode correspondante de la classe qui hérite de 'Tasks 'pour inclure l'expiration d'une tâche comme condition d'erreur. (Si toutefois celle-ci est définie dans la configuration de la tâche) Method ErrorCondition:Bool() Local endTask:Bool = False If Self.settings.expirationDelay <> - 1 Then endTask = Self.HasExpired() EndIf Return endTask Or Self.HasErrors() End 'summary: Affiche le rendu associé à la tâche à l'écran. Method Render:Void() End 'summary: Méthode éxécuté lorsque la tâche est éxécuté. Method Execute:Void() End 'summary: Méthode éxécuté lorsque la tâche est complété. Method TaskCompleted:Void() End 'summary: Méthode éxécuté lorsque la tâche est en erreur. Method TaskError:Void(reason:String, errorCode:Int) End 'summary: Considéré la tâche comme terminée avec code d'erreur et raison sans considéré la condition de fin. Method Terminate:Void(hasErrors:Bool, errorCode:Int, reason:String) Self.isFinished = True Self.hasErrors = hasErrors Self.terminateReason = reason End 'summary: Considéré la tâche comme terminée avec code d'erreur sans considéré la condition de fin. Method Terminate:Void(hasErrors:Bool, errorCode:Int) Self.Terminate(hasErrors, errorCode, "") End 'summary: Considéré la tâche comme terminée avec raison sans considéré la condition de fin. Method Terminate:Void(hasErrors:Bool, reason:String) Self.Terminate(hasErrors, -1, reason) End 'summary: Considéré la tâche comme terminée sans considéré la condition de fin. Method Terminate:Void() Self.Terminate(False, -1, "") End End 'summary: Représente une tâche avec un objet de travail. Class TaskObject < T > Extends Task Private Field workObject:T Public 'summary: Construire une tâche avec objet de travail. Method New(taskId:Int, settings:TaskSettings, workObject:T) Super.New(taskId, settings) Self.workObject = workObject End 'summary: Obtenir l'objet de travail associé à la tâche. Method WorkObject:T() Property Final Return Self.workObject End 'summary: Définir l'objet de travail associé à la tâche. Method WorkObject:Void(workObject:T) Property Final Self.workObject = workObject End End 'summary: Représente un gestionnaire de groupe de tâches pour gérer plusieurs gestionnaires de tâches. Class TasksGroupHandler Private Field tasksHandlerList:List<TasksHandler> Public 'summary: Construire un gestionnaire de groupe de tâches. Method New() Self.tasksHandlerList = New List<TasksHandler>() End 'summary: Enregistrer un gestionnaire de tâches au groupe. Method Register:Void(tasksHandler:TasksHandler) Self.tasksHandlerList.AddLast(tasksHandler) End 'summary: Vider la liste des gestionnaires de tâches. Method Clear:Void() Self.tasksHandlerList.Clear() End 'summary: Terminer toutes les tâches ayant l'identifiant passé en paramètre de toutes les gestionnaires de tâches enregistrés dans le groupe. Method TerminateTask:Void(taskId:Int, hasErrors:Bool, errorCode:Int, reason:String) For Local th:TasksHandler = EachIn Self.tasksHandlerList th.TerminateTask(taskId, hasErrors, errorCode, reason) Next End 'summary: Mettre à jour l'ensemble des tâches des gestionnaires de tâches. Method UpdateTasks:Void() For Local th:TasksHandler = EachIn Self.tasksHandlerList th.UpdateTasks() Next End 'summary: Afficher le rendu de l'ensemble des tâches des gestionnaires de tâches. Method RenderTasks:Void() For Local th:TasksHandler = EachIn Self.tasksHandlerList th.RenderTasks() Next End End |
| ||
I made a sample but the behavior is not reproductible. http://sdrv.ms/ZyUr94 |
| ||
Can you email me the project? |
| ||
Yes i can. Will do this evening. |
| ||
I have sent you the source code of my project + .js of bug scenario and .js of working scenario depending of if you include tasks to the reflection filter. Thanks a lots for your help! If you have any questions feel free to reply to my email. |
| ||
I sent you an update by mail. Seem to have found the problem. However that still strange.. |