Iavra

[Ace] Game Localization - Core Engine

May 28th, 2015
313
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #==============================================================================
  2. # Iavra Game Localization - Core Engine 1.00
  3. # -----------------------------------------------------------------------------
  4. # Description:
  5. # Loads language files for the database and messages modules and manages the
  6. # current language
  7. # -----------------------------------------------------------------------------
  8. # Prerequisites:
  9. # (optional) Iavra Game.ini Access
  10. # -----------------------------------------------------------------------------
  11. # How to Use:
  12. # To get an set the current language, call the follwoing methods:
  13. #
  14. # IAVRA::I18N.language
  15. # IAVRA::I18N.language=
  16. #
  17. # Languages are stored in symbol form, like :en or :de. By default, the script
  18. # stores the current language in its own file. If "Iavra Game.ini Access" is
  19. # present, it will be stored in the Game.ini file, instead.
  20. #
  21. # Language files are basically Ruby hashes and built like this:
  22. #
  23. # {
  24. #   :category =>
  25. #   {
  26. #     # module dependent
  27. #   }
  28. # }
  29. #
  30. # Localized text can be accessed by calling the following method:
  31. #
  32. # IAVRA::I18N[category]
  33. #
  34. # The language of a file is defined by its name and/or directory.
  35. # -----------------------------------------------------------------------------
  36. # Terms of Use:
  37. # Free to use for both commercial and non-commercial games. Please give credit.
  38. # -----------------------------------------------------------------------------
  39. # Credits:
  40. # Iavra
  41. # -----------------------------------------------------------------------------
  42. # Changelog:
  43. # - 1.00: Release version.
  44. #==============================================================================
  45.  
  46. ($imported ||= {})[:iavra_i18n_core] = true
  47.  
  48. #==============================================================================
  49. # ▼ IAVRA::I18N::CORE
  50. #==============================================================================
  51.  
  52. module IAVRA
  53.     module I18N
  54.         module CORE
  55.            
  56.             #========================================================================
  57.             # ■ ■ ■ ■ ■ CONFIGURATION ■ ■ ■ ■ ■
  58.             #========================================================================
  59.            
  60.             #========================================================================
  61.             # Lists all languages, that should be supported by the script.
  62.             #========================================================================
  63.            
  64.             LANGUAGES = [:en, :de]
  65.            
  66.             #========================================================================
  67.             # Defines the path, where language files will be loaded from. %s is
  68.             # replaced by one of the entries of LANGUAGES and the whole string is
  69.             # treated as a file glob.
  70.             #========================================================================
  71.            
  72.             FILE_PATH = "I18N/%s{_*,}.rb"
  73.            
  74.             #========================================================================
  75.             # This file is used to store the current language. If "Iavra Game.ini
  76.             # Access" is present, the Game.ini file will be used, instead.
  77.             #========================================================================
  78.            
  79.             PERSISTENCE = "I18N/current.txt"
  80.            
  81.             #========================================================================
  82.             # Setting this to true will enable deep merging for loaded files, which
  83.             # allows to split categories over multiple files.
  84.             #========================================================================
  85.            
  86.             DEEP_MERGE = false
  87.            
  88.             #========================================================================
  89.             # Setting this to true will cause language files to be loaded inside
  90.             # their own thread, which acts as a sandbox. Since the files are read in
  91.             # using eval, they could interact with the rest of your game if this is
  92.             # set to false.
  93.             #========================================================================
  94.            
  95.             SANDBOX = false
  96.            
  97.             #========================================================================
  98.             # ■ ■ ■ ■ ■ CONFIGURATION ■ ■ ■ ■ ■
  99.             #========================================================================
  100.            
  101.             class << self
  102.                 attr_accessor :language
  103.                 attr_reader :language_map
  104.             end
  105.            
  106.             #========================================================================
  107.             # Sandbox'ed eval, which runs inside its own thread with $SAFE = 4. This
  108.             # is as close to a sandbox as i can get.
  109.             #========================================================================
  110.            
  111.             def self.sandbox_eval(data)
  112.                 Thread.new{
  113.                     $SAFE = 4
  114.                     Thread.current[:result] = eval(data)
  115.                 }.join[:result]
  116.             end
  117.            
  118.             #========================================================================
  119.             # Methods for loading and saving the current language
  120.             #========================================================================
  121.            
  122.             if(($imported ||= {})[:iavra_ini_access])
  123.                
  124.                 def self.load_language
  125.                     value = IAVRA::INI.load("i18n", "Language", "-").to_sym
  126.                     value == :- ? nil : value
  127.                 end
  128.                
  129.                 def self.save_language
  130.                     IAVRA::INI.save("i18n", "Language", @language)
  131.                 end
  132.                
  133.             else
  134.                
  135.                 def self.load_language
  136.                     File.file?(PERSISTENCE) ? File.open(PERSISTENCE) {|file| file.read.to_sym} : nil
  137.                 end
  138.                
  139.                 def self.save_language
  140.                     File.open(PERSISTENCE, "w") {|file| file.write(@language.to_s)}
  141.                 end
  142.                
  143.             end
  144.            
  145.             #========================================================================
  146.             # Loads the current language on game starts. Defaults to the first entry
  147.             # in LANGUAGES, if no saved language can be found.
  148.             #========================================================================
  149.            
  150.             def self.initialize_current_language
  151.                 @language = load_language || (flag = LANGUAGES[0])
  152.                 @language = nil if !LANGUAGES.include?(@language)
  153.                 save_language if flag
  154.             end
  155.            
  156.             #========================================================================
  157.             # Loads all language files, either directly or inside a sandbox'ed eval.
  158.             # Afterwards, the files are merged to a hash.
  159.             #========================================================================
  160.            
  161.             def self.initialize_language_map
  162.                 @language_map = Hash[LANGUAGES.map{|lang|
  163.                     [lang, Dir[FILE_PATH.gsub("%s", lang.to_s)].map{|name|
  164.                         File.open(name) {|f| d = f.read; (SANDBOX ? sandbox_eval(d) : eval(d)) || {}}
  165.                     }.inject(DEEP_MERGE ? :iavra_i18n_deep_merge : :merge)]
  166.                 }]
  167.             end
  168.            
  169.         end
  170.        
  171.         #==========================================================================
  172.         # The initialize method is located outside the CORE module to make it
  173.         # easier for the modules to hook themselves into it.
  174.         #==========================================================================
  175.        
  176.         def self.initialize
  177.             CORE.initialize_current_language
  178.             CORE.initialize_language_map
  179.         end
  180.        
  181.         #==========================================================================
  182.         # This is called once at game start and whenever the current language is
  183.         # changed and can be used by modules to perform actions.
  184.         #==========================================================================
  185.        
  186.         def self.update
  187.         end
  188.        
  189.         #==========================================================================
  190.         # Getter and setter for the current language
  191.         #==========================================================================
  192.        
  193.         def self.language
  194.             CORE.language
  195.         end
  196.        
  197.         def self.language=(lang)
  198.             return if lang.nil?
  199.             return if (sym = lang.to_sym) == language
  200.             return unless CORE::LANGUAGES.include?(sym)
  201.             CORE.language = sym
  202.             CORE.save_language
  203.             update
  204.         end
  205.        
  206.         #==========================================================================
  207.         # Shortcut method to access localized text
  208.         #==========================================================================
  209.        
  210.         def self.[](sym)
  211.             (CORE.language_map[language] || {})[sym] || {}
  212.         end
  213.        
  214.     end
  215. end
  216.  
  217. #==============================================================================
  218. # ▼ Hash
  219. #==============================================================================
  220.  
  221. class Hash
  222.    
  223.     #============================================================================
  224.     # recursive deep merge
  225.     #============================================================================
  226.    
  227.     def iavra_i18n_deep_merge(second)
  228.         merger = proc{|key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2}
  229.         self.merge(second, &merger)
  230.     end
  231.    
  232. end
  233.  
  234. #==============================================================================
  235. # ▼ DataManager
  236. #==============================================================================
  237.  
  238. module DataManager
  239.    
  240.     class << self
  241.         alias :iavra_i18n_core_load_database :load_database
  242.     end
  243.    
  244.     def self.load_database
  245.         iavra_i18n_core_load_database
  246.         IAVRA::I18N.initialize
  247.         IAVRA::I18N.update
  248.     end
  249.    
  250. end
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×