tests: update sav of nitserial to latest changes
[nit.git] / examples / calculator / src / calculator_logic.nit
index c5fbaf7..be55201 100644 (file)
@@ -1,7 +1,5 @@
 # This file is part of NIT ( http://www.nitlanguage.org ).
 #
-# Copyright 2013-2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 # Business logic of a calculator
 module calculator_logic
 
+import json::dynamic
+
+# Hold the state of the calculator and its services
 class CalculatorContext
+       # Result of the last operation
        var result: nullable Numeric = null
 
+       # Last operation pushed with `push_op`, to be executed on the next push
        var last_op: nullable Char = null
 
+       # Value currently being entered
        var current: nullable FlatBuffer = null
+
+       # Text to display on screen
        fun display_text: String
        do
                var result = result
@@ -51,7 +57,8 @@ class CalculatorContext
                return buf.to_s
        end
 
-       fun push_op( op : Char )
+       # Push operation `op`, will usually execute the last operation
+       fun push_op(op: Char)
        do
                apply_last_op_if_any
                if op == 'C' then
@@ -65,7 +72,8 @@ class CalculatorContext
                self.current = null
        end
 
-       fun push_digit( digit : Int )
+       # Push a digit
+       fun push_digit(digit: Int)
        do
                var current = current
                if current == null then current = new FlatBuffer
@@ -78,6 +86,7 @@ class CalculatorContext
                end
        end
 
+       # Switch entry mode from integer to decimal
        fun switch_to_decimals
        do
                var current = current
@@ -86,7 +95,8 @@ class CalculatorContext
                self.current = current
        end
 
-       fun apply_last_op_if_any
+       # Execute the last operation it not null
+       protected fun apply_last_op_if_any
        do
                var op = last_op
 
@@ -106,9 +116,56 @@ class CalculatorContext
                else if op == '*' then
                        result = result.mul(current.to_n)
                end
+
                self.result = result
                self.current = null
        end
+
+       # Serialize calculator state to Json
+       fun to_json: String
+       do
+               # Do not save NaN nor inf
+               var result = self.result
+               if result != null and (result.to_f.is_nan or result.to_f.is_inf != 0) then result = null
+
+               var self_last_op = self.last_op
+               var last_op
+               if self_last_op == null then
+                       last_op = "null"
+               else last_op = "\"{self_last_op}\""
+
+               var self_current = self.current
+               var current
+               if self_current == null then
+                       current = "null"
+               else current = "\"{self_current}\""
+
+               return """
+{
+       "result": {{{result or else "null"}}},
+       "last_op": {{{last_op}}},
+       "current": {{{current}}}
+}"""
+       end
+
+       # Load calculator state from Json
+       init from_json(json_string: String)
+       do
+               var json = json_string.to_json_value
+               if json.is_error then
+                       print "Loading state failed: {json.to_error}"
+                       return
+               end
+
+               var result = json["result"]
+               if result.is_numeric then self.result = result.to_numeric
+
+               var last_op = json["last_op"]
+               if last_op.is_string then self.last_op = last_op.to_s.chars.first
+
+               var current = json["current"]
+               if current.is_string then self.current = new FlatBuffer.from(current.to_s)
+       end
 end
 
 redef universal Float