diff --git a/Manual/GenerateKeyboardShortcutTableFromJson.py b/Manual/GenerateKeyboardShortcutTableFromJson.py index e01ba4c91..bb5a4cd7f 100644 --- a/Manual/GenerateKeyboardShortcutTableFromJson.py +++ b/Manual/GenerateKeyboardShortcutTableFromJson.py @@ -1,21 +1,18 @@ -### Python script to generate copy-pasteable HTML tables from JSON files +### Python script to generate copy-pasteable HTML tables from JSON file ### -### Provide the full directory path to the .json files as the command line argument. +### Provide the full directory path to the .json file as the command line argument. ### The output HTML file will also be placed there. -### For example: CMD > python GenerateKeyboardShortcutTableFromJson.py "C:/Users/Dev/Documents/GitHub/ameMaker-Manual/Manual/" -name_as_desc -env beta -update_rh_vars +### For example: CMD > python GenerateKeyboardShortcutTableFromJson.py "C:/Users/Dev/Documents/GitHub/GameMaker-Manual/Manual/" -name_as_desc -env beta ### ### You can provide a few optional arguments: ### ### -name_as_desc: Add this to write the hotkey's name as the description. -### -env: Provide this, followed by the environment in which you want to look for the JSON files +### -env: Provide this, followed by the environment in which you want to look for the JSON file ### (one of: "dev", "lts", "beta", "prod") ### Note: only works on Windows! ### -update_rh_vars: Add this to update the RoboHelp variables ### A RH variable is written (or updated if exists) for every Win/Mac shortcut ### For example: Hotkey_Create_Asset_Win, Hotkey_Create_Asset_Mac -### -### Important: Technically, the JSON cannot contain trailing commas, this isn't supported -### using the built-in json module. Though it is supported through the yy_load function. ### import sys @@ -30,18 +27,8 @@ # Unique modifier keys mods = set() -def yy_load(file): - """ Load json from a file that possibly contains trailing commas """ - # Do some tricky regex substitution - # so we can use the json module - data_string = ''.join(file.readlines()) - data_string = re.sub("(,)(\s*[]}])","\g<2>", data_string) - - # Now we can import using the json module - return json.loads(data_string) - # Utility functions -def get_combo_string(combo): +def get_combo_string(combo, replace_in_names=[]): global mods if not combo: combo_string = "" @@ -55,11 +42,14 @@ def get_combo_string(combo): else: # This is a regular hotkey combo_string = " + ".join([*modifier, combo['Keys']]) + + if replace_in_names: + for item in replace_in_names: + combo_string = combo_string.replace(item[0], item[1]) return combo_string # Default names -fname_win_hotkeys = "default_hotkeys.json" -fname_mac_hotkeys = "mac_hotkeys.json" +fname_hotkeys = "default_hotkeys.json" install_dirs = { "dev": "GameMaker-Dev", @@ -98,10 +88,9 @@ def get_combo_string(combo): exit() # Check if files exist -fpath_win = in_dir + os.sep + fname_win_hotkeys -fpath_mac = in_dir + os.sep + fname_mac_hotkeys -if not os.path.isfile(fpath_win) or not os.path.isfile(fpath_mac): - print("ERROR - One or more files doesn't exist. Exiting...") +fpath_win = in_dir + os.sep + fname_hotkeys +if not os.path.isfile(fpath_win): + print("ERROR - Shortcuts file doesn't exist. Exiting...") exit() # Data structures @@ -109,11 +98,10 @@ def get_combo_string(combo): shortcuts = dict() # maps shortcut name => shortcut data shortcuts_per_location = OrderedDict() # stores shortcuts under locations -# First read the Windows defaults file +# Read the defaults file with open(fpath_win, 'r', encoding="utf-8") as f: # Load all the data - # input = json.load(f) # risk of errors if trailing commas are present - input = yy_load(f) # regex-replace variety that fixes things + input = json.load(f) # risk of errors if trailing commas are present # Add items under their respective locations (i.e. "group" per location) for shortcut in input: @@ -139,6 +127,20 @@ def get_combo_string(combo): # "Localisation": combo['Localisation'] } + # Store platform overrides, if there are any + if 'PlatformOverrides' in shortcut and shortcut['PlatformOverrides']: + for override in shortcut['PlatformOverrides']: + if override['Platform'] != 'MacOs': + continue + + # Get this shortcut's Mac combo(s) + cbo = override['Combo'] + combos = [cbo] if type(cbo) is not list else cbo + combo_strings = [get_combo_string(combo, replace_in_names=[("Windows", "Command")]) for combo in combos] + + # Assign to final output + shortcuts[name]['mac_combo'] = combo_strings + # Store name of shortcut under all its locations loc = shortcut['Location'] locations = [loc] if (type(loc) == str) else loc @@ -151,28 +153,6 @@ def get_combo_string(combo): # Add the shortcut shortcuts_per_location[location][name] = name -# Then add the combos in the macOS defaults file -with open(fpath_mac, 'r') as f: - # Load all the data - input = yy_load(f) - - # Add items under their respective locations - for shortcut in input: - # Get unique name - name = shortcut['Name'] - - # Nothing to do for unlisted shortcuts - if name not in shortcuts: - continue - - # Get this shortcut's combo(s) - cbo = shortcut['Combo'] - combos = [cbo] if type(cbo) is not list else cbo - combo_strings = [get_combo_string(combo) for combo in combos] - - # Just overwrite the macOS combo under the right name here - shortcuts[name]['mac_combo'] = combo_strings - # Generate HTML html = "" for location in shortcuts_per_location: diff --git a/Manual/_page_generation/Template_Code_Page.htm b/Manual/_page_generation/Template_Code_Page.htm index a4d5eb900..5969fe979 100644 --- a/Manual/_page_generation/Template_Code_Page.htm +++ b/Manual/_page_generation/Template_Code_Page.htm @@ -16,7 +16,6 @@
Keyword Description Goes Here.
-Additional Information Goes Here.
(arguments);
diff --git a/Manual/contents/Additional_Information/Additional_Information.htm b/Manual/contents/Additional_Information/Additional_Information.htm index 1f23aca17..6610fdc60 100644 --- a/Manual/contents/Additional_Information/Additional_Information.htm +++ b/Manual/contents/Additional_Information/Additional_Information.htm @@ -18,6 +18,7 @@This section of the manual contain a collection of miscellaneous articles related to programming and the way the GameMaker Language works. The following articles are designed as companion articles to further expand your understanding of how GameMaker works and how to get the most from the different language features available:
@@ -42,7 +44,7 @@
One of the first assets you work with in GameMaker are Objects. An object lets you define how something in your game behaves (e.g. a player or enemy).
+Then in The Room Editor, you drag an object into a room, so it actually appears in-game. That's where an object stops and an instance begins.
+An instance is created from an object and you can have multiple instances of an object in a room. Each instance can go its own way and you can modify each instance of an object separately.
+Understanding the difference between objects and instances is important as they both exist as resources at runtime.
+Instances are prominent at runtime as they are the primary drivers of your game: they are the ones executing your code and interacting with other instances to form gameplay. Objects on the other hand continue to exist as background resources, and they can be modified and used to create new instances.
+There are functions and language features that operate on both objects (the background resource) and instances (its actual presence in the room), and as such it becomes important to understand the differences between using either resource in such functions.
+You can access variables from an instance via dot notation, i.e. instance.variable. You can also use an object in place of the instance (object.variable) which is fine if there is only one instance of that object, however it is not recommended if there are more than one, as it would just return the value from the first instance created for that object (which may change).
+To understand how the dot accessor works with objects and instances, see Addressing Variables In Other Instances.
+You can also access the scope of an instance or all instances of an object using with(). See the with page for details on how it works using objects and instances.
+There are built-in GML functions that operate on either an object handle or an instance handle, depending on the function.
+Functions that only take an object handle usually return information on all of its instances, such as instance_number, on the object itself, such as object_get_name, and on one particular instance of the object, such as instance_nearest and instance_create_layer (in this case, creating a new one). Another example is the function instance_change which operates on the current instance and changes it to use a different object (and hence use its events).
+Functions that only operate on instances mostly do so without arguments, as they operate on the instance executing the code. For example, instance_change as previously mentioned, instance_copy, motion_add and various other functions will operate on the current instance. There are functions that operate on instances via arguments, but they also accept object handles and are covered in the next section.
+There are built-in GML functions that take both an instance handle and an object handle.
+The difference in most use cases is simple: passing an instance handle only modifies that one instance, and passing an object handle modifies all instances of the given object.
+Pages for functions that take both types of values will explain the difference between passing either. Here are some common examples of functions that take both:
+Using a parent object in any of the functions above is the same as passing all its child objects as well. The operation will include all instances of the given object and all instances of its child objects (and their child objects if they have any, and so on).
++
+
+ + + + + +