Loading Data from File
#1
Loading Data from File
Version: 1.0


Introduction
This script will allow a scripter to load data from a text file. Great for scripts that require large amounts of data and you don't want to define things using the database or the script editor. The script will catch many different errors while reading from the file (Syntax Errors, Missing } for hashes and Missing ] for arrays) and tells the line(s) and data where the error was found. Also This Tool can load data on multiple lines. And Organizes the information loaded.


Screenshots
Yeah that will help.


Script
Code:
module Trickster
  class File_LoadRxdata < File
    attr_accessor :line
    
    def format_readline
      data = self.readline
      @line = data.dup
      data = data.split(/\s/)
      data.delete("")
      return data
    end
    
    def requirements(data, required, properties)
      for i in required
        if data[i].nil? and i < properties.size
          s1 = "Error Loading Data"
          s2 = "\n#{properties[i]} is undefined"
          Kernel.print(s1+s2)
          exit
        end
      end
    end
      
    def error_incorrect_name
      s1 = "Error Loading Data at Line number #{file.lineno}"
      s2 = "\nIncorrect defining name"
      s3 = "\nLine data: #{self.line}"
      Kernel.print(s1+s2+s3)
      exit
    end
      
    def error_array(extra)
      s1 = "Error Loading Data at Line number#{extra}"
      s2 = "\nMissing ']' for Array"
      s3 = "\nLine data: #{self.line}"
      Kernel.print(s1+s2+s3)
      exit
    end
      
    def error_hash(extra)
      s1 = "Error Loading Data at Line number#{extra}"
      s2 = "\nMissing '}' for Hash"
      s3 = "\nLine data: #{self.line}"
      Kernel.print(s1+s2+s3)
      exit
    end
          
    def error_syntax(extra)
      s1 = "Error Loading Data at Line number#{extra}"
      s2 = "\nSyntax Error"
      s3 = "\nLine Data: #{self.line}"
      Kernel.print(s1+s2+s3)
      exit
    end
    
    def load_next_line
      return false if self.eof?
      data = self.format_readline
      return true if data == [] or data[0].include?("#")
      return data
    end
    
    def test_type(data, line, lineno, multi = 0)
      # make a copy of the data
      temp = data.dup
      # set extra text if an error is found
      extra = (multi > 0) ? "s #{lineno}-#{lineno+multi}" : " #{lineno}"
      if temp == "nil" #If a nil reference
        data = nil
      elsif temp.slice(0..0) == "[" #if an array
        if !temp.include?("]")
          self.error_array(extra)
        end
        begin
          data = eval(data)
        rescue SyntaxError
          self.error_syntax(extra)
        end
      elsif temp.slice(0..0) == "{" #if a hash      
        if !temp.include?("}")
          self.error_hash(extra)
        end
        begin
          data = eval(data)
        rescue SyntaxError
          self.error_syntax(extra)
        end
      elsif test_int(temp) #If a number or "0"
        data = data.to_i
      end
      #else it is a string so just return
      return data
    end
      
    def test_int(data)
      flag = true
      for i in 0...data.length
        test = data.slice(i..i)
        if test == "0" or test.to_i != 0
          flag = flag && true
        else
          flag = false
        end
      end
      return flag
    end
  end
    
  
  #loading data from a text file
  #inputs:  file_name  = file name to load
  #         properties = defining values (see example)
  #         required   = required values to be loaded
  #         multi_lined = defining values that accept multiple lines (strings only)
  #returns: an array with the data from text file
  def self.load_data_from_txt(file_name, properties, required = [0], multi_lined = [])
    # Initialize local variables
    final_data = []
    data_txt = []
    index = 1
    # Load File
    file = Trickster::File_LoadRxdata.open(file_name)
    # Loop until End of File (EOF)
    until file.eof?
      # Get line data
      data = file.format_readline
      # Get Line
      line = file.line
      # Next if no data or commented line
      next if data == [] or data[0].include?("#")
      # Get id from the properties
      id = properties.index(data[0])
      # If a new id
      if id == 0 and data_txt != []
        # Check requirements and return error if not fulfilled
        file.requirements(data_txt, required, properties)
        # Finished reading a piece of data
        final_data[index] = data_txt.dup
        # Increase index and reset data
        index += 1
        data_txt = []
      elsif id == nil
        # Incorrent Defining name error message
        file.error_incorrect_name
      end
      # Remove defining name and join together
      data.delete_at(0)
      data = data.join(' ')
      # Get line number
      lineno = file.lineno
      # Start multi line information checking
      multi = 1
      if multi_lined.include?(id)
        # Load next line
        next_line = file.load_next_line
        # Get first data
        first = next_line.is_a?(Array) ? next_line[0] : ""
        # Reset flag
        flag = false
        # While an invalid property and the file is not eof? or data loaded
        while (properties.index(first) == nil and (next_line != false or next_line.is_a?(Array)))
          # While was excuted once
          flag = true
          position = file.pos
          # add to data if an array
          if next_line.is_a?(Array)
            # Get property data
            first = next_line[0]
            if properties.index(first) == nil
              data += ' ' + next_line.join(' ')
            end
          end
          # Load next line and reset first
          next_line = file.load_next_line
          first = ""
          # increase multi line count
          multi += 1
          # break if file.eof? continue if line was a comment
          break if next_line == false
          next if next_line == true
          first = next_line[0]
        end
        if flag
          file.pos = position
        end
        if next_line.is_a?(Array)
          if properties.index(first) == nil
            data += next_line.join(' ')
          end
        end
      end      
      data = file.test_type(data, line, lineno, multi)
      data_txt[id] = data
    end
    # Reached End of File Get last data if any
    if data_txt != []
      # Check requirements and return error if not fulfilled
      file.requirements(data_txt, required, properties)
      # Finished reading a piece of data
      final_data[index] = data_txt
      # Increase index and reset data
      index += 1
      data_txt = []
    end
    # return all data compacted
    return final_data.compact
  end
end

Instructions

To call just use use

data = Trickster.load_data_from_txt(file, properties[, required, multi_lined])
file is the file to load for reading
properties are the defining names of the data you want to load
required is the names that must be defined (by default the first item is required)
multi_lined are the defining names whose data can be defined on multiple lines

An Example Call
Code:
Scene_Title method main additions
load_mission_info
if @load_mission
  if Mission::Constants::SAVE_DATA
    save_data($data_missions, "Data/Missions2.rxdata")
  end
else
  $data_missions        = load_data("Data/Missions2.rxdata")
end

  def load_mission_info
    properties = []
    properties[0] = "id"
    properties[1] = "name"
    properties[2] = "icon"
    properties[3] = "cost"
    properties[4] = "rank"
    properties[5] = "switch"
    properties[6] = "area"
    properties[7] = "skills"
    properties[8] = "items"
    properties[9] = "mission"
    properties[10] = "random"
    properties[11] = "cancel"
    properties[12] = "penalty"
    properties[13] = "reward"
    properties[14] = "description"
    filename = "Data\\Missions.rxdata"
    @load_mission = true
    begin
      $data_missions = [nil]
      missions = Trickster.load_data_from_txt(filename,properties,[0,1],[14])
      for mission in missions
        $data_missions[mission[0]] = RPG::Mission.new(mission)
      end
    rescue
      #project is encrypted the file can't be found
      @load_mission = false
    end
  end

and the corresponding text file will look like this
Code:
id        1
name        Ghosts!?!
icon        battle_icon
cost        200
rank        1
switch        1
description    A C[C0C0C0]GhostC[N] has been spotted near the lake can someone please
get rid of him. Meet me outside this building if you take this request.
N[]T[]~Some random guy
area        [1]
skills        nil
items        nil
mission        nil
random        nil
cancel        false
penalty        nil
reward        {'gold' => 500,'combat' => 10, 'weapons' => 2}

id        2
name        Help Me!!
icon        note_icon
cost        150
rank        1
switch        2
area        [1]
skills        {'negotiate' => 1}
items        nil
mission        [1]
random        nil
cancel        true
penalty        {'gold' => 50}
reward        {'negotiate' => 3, 'weapons' => 2, 'items' => 3}
description    Can someone please buy this item off of me. My shop is going out of business
and I need the money to feed my family. Meet me near the river if you choose to take this request.
N[]T[]~Shop owner


FAQ
Note: Permission granted by Trickster to post:
Quote:And if you post what you have now of my stuff then you don't have the latest versions. I'm too lazy/busy to post stuff.
As this is his material, it is deletable upon his request. Due to his current absense, no support is available. Please do not PM or eMail him for support.


Compatibility
Compatible with everything


Terms and Conditions
Hey, I posted this publicly. You can use it. What do you expect? But if you do use it, I do expect you to spell my name correctly in your game. And yes you can use it in commercial games too.
Reply }


Possibly Related Threads…
Thread Author Replies Views Last Post
   Saving Temporary Actors' Data kyonides 1 4,897 09-07-2018, 06:40 AM
Last Post: kyonides
   LILY'S MEGA DATA! DerVVulfman 1 6,888 08-28-2017, 08:07 PM
Last Post: EricandTheCheat
   Moghunter Menus: Scene File Ayumi DerVVulfman 4 14,442 07-28-2016, 05:13 PM
Last Post: Djigit
   DerVVulfman's Game Data Sneak DerVVulfman 1 7,460 04-03-2013, 08:42 PM
Last Post: Taylor
   File Missing Error Preventer xnadvance 0 5,981 05-29-2011, 05:24 AM
Last Post: xnadvance
   Card Game Data Structure Trickster 5 11,440 12-09-2009, 06:38 PM
Last Post: Trickster
   Universal Data Back-Up Kain Nobel 2 7,113 04-19-2009, 12:33 PM
Last Post: Kain Nobel
   Audio File Encryption Dark-Yen 0 5,385 03-08-2008, 06:35 AM
Last Post: Dark-Yen
   Load file error dialog Zeriab 0 4,619 03-06-2008, 06:00 AM
Last Post: Zeriab



Users browsing this thread: 1 Guest(s)