User Tools

Site Tools


pcb:preferences_subsystem

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision Both sides next revision
pcb:preferences_subsystem [2020/10/04 18:37]
cparker
pcb:preferences_subsystem [2020/10/04 21:39]
cparker
Line 12: Line 12:
  
 === Process === === Process ===
 +One of the considerations here is separating the storage and application so that the methods can change. If we decide we'd rather store preferences in an SQL database, we can do that without having to rewrite the whole system. We only have to write functions to load and save the key values pairs in the database.
 +
 +I'm not too worried about the speed of these routines, so, it doesn'​t matter much if the lists are sorted. Reading, applying, collecting, and writing preferences doesn'​t happen very often.
 +
 +== Original Idea == 
 Originally, I was going to do it this way... but this is just extra work. So, I'm ditching the intermediate step. Originally, I was going to do it this way... but this is just extra work. So, I'm ditching the intermediate step.
 I'm breaking the preferences process into four steps: I'm breaking the preferences process into four steps:
  
- 1. Read the preferences file and create a list of key value pairs (preference items) \\ pilist = ppm_read_pref_file(fname);​ \\ This returns a list of PreferenceItem objects that contains the keys and values read out of the specified file. + Read the preferences file and create a list of key value pairs (preference items) \\ pilist = ppm_read_pref_file(fname);​ \\ This returns a list of PreferenceItem objects that contains the keys and values read out of the specified file. 
- 2. Apply preferences to the PCB data structures \\ ppm_apply_preferences(pdlist,​ pilist); \\ This iterates over the PreferenceItems in pilist. For each item it looks up the key in a preference definition list, pdlist, and calls the function associated with that preference definition. + Apply preferences to the PCB data structures \\ ppm_apply_preferences(pdlist,​ pilist); \\ This iterates over the PreferenceItems in pilist. For each item it looks up the key in a preference definition list, pdlist, and calls the function associated with that preference definition. 
- 3. Collect preferences from PCB data structures \\ pilist = ppm_collect_preferences(pdlist);​ \\ This goes through the preferences definitions in pdlist and creates a set of key value pairs, pilist, that can be stored in the text file. + Collect preferences from PCB data structures \\ pilist = ppm_collect_preferences(pdlist);​ \\ This goes through the preferences definitions in pdlist and creates a set of key value pairs, pilist, that can be stored in the text file. 
- 4. Write the preference data to a file. \\ ppm_write_pref_file(pilist);​ \\ Store the preferences in a file.+ Write the preference data to a file. \\ ppm_write_pref_file(pilist);​ \\ Store the preferences in a file.
  
-Instead we're going to go with just a two step process. The read and write functions will take a pointer to a list of PreferenceItems. The readers and writers can interact explicitly with the data they are reading/​writing and there'​s no need to build an intermediate list. +== New Idea == 
- +Instead we're going to go with just a two step process. The read and write functions will take a pointer to a list of PreferenceItems. The readers and writers can interact explicitly with the data they are reading/​writing and there'​s no need to build an intermediate list. This better supports the option for alternate storage formats
-One of the considerations here is separating the storage and application so that the methods can change. If we decide we'd rather ​store preferences ​in an SQL database, we can do that without having to rewrite ​the whole system. We only have to write functions to load and save the key values pairs in the database. + * load_preferences(file,​ preflist) 
- + *# open the preference ​store 
-I'm not too worried about the speed of these routines, so, it doesn't matter much if the lists are sortedReadingapplying, collecting, and writing preferences doesn'​t happen very often.+ *# for each item in the store 
 + *## Look up the preference ​in the preflist 
 + *## get a reader: check for a reader in the structure and use it if it's there. Otherwise lookup ​the default reader for the preference type. 
 + *## apply the reader to set the preference 
 + * save_preferences(preflistfile) 
 + *# for
  
 === Data Structures === === Data Structures ===
 We're going to draw heavily on the work that's already been done with the preferences (HIDAttributes) in designing the data structures for this system. ​ We're going to draw heavily on the work that's already been done with the preferences (HIDAttributes) in designing the data structures for this system. ​
- +== PreferenceDefinition ​== 
-==PreferenceItem== +The primary ​data structure describes a preference item. 
-A preference item contains three things, the key, the value, and the type of the value that are read and stored to the preference store. The integer type value will have to be an enum that we define. This will mostly be useful for cases where a preference is read but doesn'​t have a corresponding preference definition.  +
- +
-<code c> +
-typedef struct +
-+
-  /*! key */ +
-  char * key; +
-  /*! value */ +
-  void * value; +
-  /*! type */ +
-  int type; +
-} PreferenceItem;​ +
-</​code>​ +
- +
-The second ​data structure describes a preference item. +
  
 <code c> <code c>
Line 56: Line 51:
   /*! Human readable name of the preference */   /*! Human readable name of the preference */
   char * name;   char * name;
-  /*! preference type identifier */+  /*! preference type identifier ​(enum) ​*/
   int type;   int type;
   /*! Text that describes what the preference influences */   /*! Text that describes what the preference influences */
Line 66: Line 61:
   /*! data pointer passed to reader and writer */   /*! data pointer passed to reader and writer */
   void * ptr;   void * ptr;
-  /*! a string ​that can be used to initialize the preference */ +  /*! a value that can be used to initialize the preference; type defined as per above. ​*/ 
-  ​char default_str;+  ​void default_val;
 } PreferenceDefinition;​ } PreferenceDefinition;​
 </​code>​ </​code>​
Line 73: Line 68:
 There will be a number of "​reader"/"​writer"​ functions implemented by default to handle common data types like floats, ints, coords, etc. The data pointer will be passed to the reader and writer functions, and could contain anything. But it probably is a pointer to the variable to be set by the converted value from the PreferenceItem. Using function pointers like this allows for a lot of flexibility in how subsystems can use this code. The reader functions, for example, may also be responsible for notifying a GUI that the preference has been updated. There will be a number of "​reader"/"​writer"​ functions implemented by default to handle common data types like floats, ints, coords, etc. The data pointer will be passed to the reader and writer functions, and could contain anything. But it probably is a pointer to the variable to be set by the converted value from the PreferenceItem. Using function pointers like this allows for a lot of flexibility in how subsystems can use this code. The reader functions, for example, may also be responsible for notifying a GUI that the preference has been updated.
  
-Note: the default_str ​should initialize the value to something that is SAFE, i.e. something that will never, ever cause PCB to crash.+Note: the default_val ​should initialize the value to something that is SAFE, i.e. something that will never, ever cause PCB to crash
 + 
 +== PreferenceItem == 
 +A preference item contains three things, the key, the value, and the type of the value that are read and stored to the preference store. The integer type value will have to be an enum that we define. This will mostly be useful for cases where a preference is read but doesn'​t have a corresponding preference definition.  
 + 
 +<code c> 
 +typedef struct 
 +
 +  /*! key */ 
 +  char * key; 
 +  /*! value */ 
 +  void * value; 
 +  /*! type */ 
 +  int type; 
 +} PreferenceItem;​ 
 +</​code>​ 
 + 
 +== Lists == 
 +Presently, the intent is to use object_list for all of the lists.
  
 === Implementation Overview === === Implementation Overview ===
Line 104: Line 117:
  
 === Functions === === Functions ===
-There are a number of key functions here: load_preferences,​ save_preferences, read_pref_file,​ write_pref_file,​ apply_preferences,​ collect_preferences, readers, and writers. Note that the file IO is being deliberately kept separate so that the actual file format is independent. Also, this allows data from a single file to be scanned more than once against different preference registries. We saw some pseudo-code for the load_preferences and save_preferences above (although it should have used apply_preferences and collect_preferences instead of spelling it out). So let's think about some of the others, again in pseudo-code (python...).+There are a number of key functions here: load_preferences,​ save_preferences,​ readers, and writers. Note that the file IO is being deliberately kept separate so that the actual file format is independent. Also, this allows data from a single file to be scanned more than once against different preference registries. We saw some pseudo-code for the load_preferences and save_preferences above (although it should have used apply_preferences and collect_preferences instead of spelling it out). So let's think about some of the others, again in pseudo-code (python...).
 <code python> <code python>
-def read_pref_file(filename):+def load_preferences(filename, pref_list):
   with open(filename,​ r) as f:   with open(filename,​ r) as f:
     f.seek(-1) # seek to the end     f.seek(-1) # seek to the end
pcb/preferences_subsystem.txt · Last modified: 2021/02/28 19:56 by cparker