#!/usr/bin/php load(); include "utils.php"; include "graph.php"; global $files; $baseExtends = 'base'; function getTokens($types) { $tokens = []; foreach ($types as $type) { $fn = fopen('src/templates/token.db', "r"); while (!feof($fn)) { $line = fgets($fn); $matches = []; if (preg_match('/^(' . $type . '.*$)/', $line, $matches)) { $tokens[$matches[1]] = []; } } fclose($fn); } return $tokens; } /** * Warning - does not do nested token extractions * @throws ErrorException */ function loadSaved($file, $tokens, $extract = false) { $saveFile = $file; // echo "loading file " . $saveFile . "\n"; $loadedTokens = []; $fn = fopen($saveFile, "r"); if (!$fn) { throw new ErrorException('Could not open save file: ' . $saveFile . "\n"); } $currentTokenKey = null; while (!feof($fn)) { $line = fgets($fn); $tokenFound = false; $justFound = false; foreach ($tokens as $key => $store) { if ( preg_match('/\b' . $key . '\b/', $line) || ($extract && preg_match('/\b' . $key . '_START\b/', $line)) ) { if (array_key_exists($key, $loadedTokens)) { throw new ErrorException("TOKEN ALREADY EXISTS! : $key\n"); } $tokenFound = true; $loadedTokens[$key] = []; $currentTokenKey = $key; break; } } if ($extract && preg_match('/\b' . $currentTokenKey . '_END\b/', $line)) { $currentTokenKey = null; } if (!$tokenFound && $line != false) { if ($currentTokenKey != null) { array_push($loadedTokens[$currentTokenKey], $line); } } } fclose($fn); return $loadedTokens; } function getFileData($file, &$tokens) { $currentTokens = []; $fn = fopen($file, "r"); while (!feof($fn)) { $line = fgets($fn); foreach ($tokens as $key => $store) { if (preg_match('/\b' . $key . '_END\b/', $line)) { array_pop($currentTokens); break; } } $size = sizeof($currentTokens); if ($size > 0) { array_push($tokens[$currentTokens[$size - 1]], $line); } foreach ($tokens as $key => $store) { if (preg_match('/\b' . $key . '_START\b/', $line)) { array_push($currentTokens, $key); break; } } } fclose($fn); } function save($file, $tokens) { // echo "saving file " . $file . "\n"; getFileData($file, $tokens); $saveFile =$file . '.saved'; $saved = []; $stores = []; foreach ($tokens as $key => $store) { if (sizeof($store) > 0) { $stores[$key] = $store; array_push($saved, $key . "\n"); foreach ($store as $line) { array_push($saved, $line); } } } file_put_contents($saveFile, $saved); // echo "saved file $saveFile\n"; return [ $saveFile, $stores ]; } function deleteSavedFile($saveFile) { if ($saveFile && file_exists($saveFile)) { unlink($saveFile); } else { echo "Did not unlink file $saveFile because it did not exist.\n"; } } function getWhitespace($contents, $token) { $matches = []; if (preg_match('/^\n*(\s*)\b' . $token . '\b/m', $contents, $matches)) { return [ 'white-space' => $matches[1], 'inline-comment' => false ]; } else { if (preg_match('/^\n*(\s*)\/\/\b' . $token . '\b/m', $contents, $matches)) { return [ 'white-space' => $matches[1], 'inline-comment' => true ]; } return null; } } function updateSection($file, $token, $updates, $separator = "") { if (getType($updates) === 'array') { $updates = implode($separator, $updates); } if (strlen($updates) <= 0) { echo "No contents to be updated for token $token\n"; return false; } if (substr($updates, -1) !== "\n") { $updates .= "\n"; } $contents = file_get_contents($file); $whiteSpaceObject = getWhitespace($contents, $token . '_END'); if ($whiteSpaceObject === null) { /** * This file does not contain the token which requires an update - we can return here */ echo "Skipping token $token because it was not found but it could be generated soon...\n"; return $token; } $endToken = $token . "_END"; if ($whiteSpaceObject['inline-comment']) { $endToken = '//' . $endToken; } $whiteSpace = $whiteSpaceObject['white-space']; $contents = preg_replace( '/\b' . $token . '_START\b.*?\b' . $token . '_END\b/s', $token . "_START\n" . $updates . $whiteSpace . $endToken, $contents ); file_put_contents($file, $contents); return true; } function getPropertyListItems($store) { $propertyListItems = []; foreach ($store as $item) { $item = trim($item); $result = preg_split('/=/', $item); $propertyListItem = '- ' . $result[0]. ' (Default value ' . $result[1] . ")"; $propertyListItem = wordwrap($propertyListItem, 100, "\n "); array_push($propertyListItems, $propertyListItem); } return $propertyListItems; } function getMethodListItems($store, $parentStore = [], $parent = null) { $methodListItems = []; foreach ($store as $item) { $overrides = false; foreach ($parentStore as $parentItem) { if (trim($parentItem) === trim($item)) { $overrides=true; } } $details = getMethodDetails($item); if ($overrides === true) { $methodListItem = '- ' . $details['methodName'] . '(' . $details['args'] . ")\n"; $methodListItem .= " " . wordwrap('Overrides for ' . $parent->nameSpace . $parent->name . '.' . $details['methodName'] . '()', 110, "\n ") . "\n"; } else { $methodListItem = '- ' . $details['methodName'] . '(' . $details['args'] . ")\n"; $methodListItem .= " " . wordwrap($details['comment'], 110, "\n ") . "\n"; } array_push($methodListItems, $methodListItem); } return $methodListItems; } function doGetInheritedTemplateUpdates($node, $restoreTokens, $inherited = true, $for) { try { $saveFile = $node->file . '.saved'; if (!file_exists($saveFile)) { save($node->file, $restoreTokens); } $tokens = loadSaved($node->file . '.saved', $restoreTokens); if ($node->parent !== null) { $parentSaveFile = $node->parent->file . '.saved'; if (!file_exists($parentSaveFile)) { save($node->parent->file, $restoreTokens); } } $parentTokens = loadSaved($node->parent->file . '.saved', $restoreTokens); } catch (ErrorException $e) { echo $e->getMessage(); exit(0); } $updates = ''; $firstTemplate = false; if ($node->parent !== null && $node->parent->name !== "R3") { $updates = rtrim(doGetInheritedTemplateUpdates($node->parent, $restoreTokens, true, $for)) . "\n"; } else { $firstTemplate = true; } $template = file_get_contents('src/templates/generated_inherited.template'); $CLASS_NAME = $node->name; $token = 'CUSTOM_OPTIONS'; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { if ($inherited) { $PROPERTY_LIST = ''; } else { $PROPERTY_LIST = ''; } } else { $propertyListItems = getPropertyListItems($store); $PROPERTY_LIST = implode("\n ", $propertyListItems); } $PROPERTY_LIST = trim($PROPERTY_LIST); $token = 'CUSTOM_STATIC_OPTIONS'; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { if ($inherited) { $STATIC_PROPERTY_LIST = ''; } else { $STATIC_PROPERTY_LIST = ''; } } else { $propertyListItems = getPropertyListItems($store); $STATIC_PROPERTY_LIST = implode("\n ", $propertyListItems); } $STATIC_PROPERTY_LIST = trim($STATIC_PROPERTY_LIST); $token = 'CUSTOM_METHODS'; $store = getTokenStore($token, $tokens); $parentStore = getTokenStore($token, $parentTokens); if (sizeof($store) <= 0) { if ($inherited) { $METHOD_LIST = ''; } else { $METHOD_LIST = ''; } } else { $methodListItems = getMethodListItems($store, $parentStore, $node->parent); $METHOD_LIST = implode("\n ", $methodListItems); } $METHOD_LIST = trim($METHOD_LIST); $token = 'CUSTOM_STATIC_METHODS'; $store = getTokenStore($token, $tokens); $parentStore = getTokenStore($token, $parentTokens); if (sizeof($store) <= 0) { if ($inherited) { $STATIC_METHOD_LIST = ''; } else { $STATIC_METHOD_LIST = ''; } } else { $methodListItems = getMethodListItems($store, $parentStore, $node->parent); $STATIC_METHOD_LIST = implode("\n ", $methodListItems); } $STATIC_METHOD_LIST = trim($STATIC_METHOD_LIST); if ($inherited) { $description = 'Inherited from'; } else { $description = 'Belonging to'; } if ($firstTemplate) { $updated = str_replace("FIRST_TEMPLATE", "Class " . $for, $template); } else { $updated = preg_replace('/^.*?FIRST_TEMPLATE.*\n/m', "", $template); } if ($inherited) { $INHERITED = 'Inherited '; } else { $INHERITED = ''; } $updated = str_replace('INHERITED', $INHERITED, $updated); $updated = str_replace('DESCRIPTION', $description, $updated); $updated = str_replace('CLASS_NAME', $CLASS_NAME, $updated); $updated = preg_replace('/\bPROPERTY_LIST\b/', $PROPERTY_LIST, $updated); $updated = preg_replace('/\bSTATIC_PROPERTY_LIST\b/', $STATIC_PROPERTY_LIST, $updated); $updated = str_replace('STATIC_METHOD_LIST', $STATIC_METHOD_LIST, $updated); $updated = str_replace('METHOD_LIST', $METHOD_LIST, $updated); $updates .= $updated; return $updates; } function generateInherited($file, $restoreTokens) { echo "Generating inherited fields for $file\n"; global $graph; $node = $graph->search('file', $file); if ($node === null) { /** * This node is not part of R3 */ return; } if ($node->parent === null) { /** * This node has no inherited properties */ return; } if ($node->parent->name === 'R3') { /** * This is a base class */ return; } $updates = doGetInheritedTemplateUpdates($node, $restoreTokens, false, $node->nameSpace . $node->nameSpaceClassName); updateSection($file, 'GENERATED_INHERITED' , $updates); } function generateConstructors($file, $command) { // echo $file; global $baseExtends; $constructor = null; $token = 'GENERATED_CONSTRUCTOR'; if (preg_match('/\bsystem_base\b/', $command)) { $constructor = file_get_contents('src/templates/system_base_constructor.template'); } if (preg_match('/\bsystem_extends\b/', $command)) { $constructor = file_get_contents('src/templates/system_extends_constructor.template'); $baseExtends = 'extends'; } if (preg_match('/\bruntime_base\b/', $command)) { $constructor = file_get_contents('src/templates/runtime_base_constructor.template'); } if (preg_match('/\bruntime_extends\b/', $command)) { $constructor = file_get_contents('src/templates/runtime_extends_constructor.template'); $baseExtends = 'extends'; } if (preg_match('/\bcomponent_base\b/', $command)) { $constructor = file_get_contents('src/templates/component_base_constructor.template'); } if (preg_match('/\bcomponent_extends\b/', $command)) { $constructor = file_get_contents('src/templates/component_extends_constructor.template'); $baseExtends = 'extends'; } if (preg_match('/\bentity_base\b/', $command)) { $constructor = file_get_contents('src/templates/entity_base_constructor.template'); } if (preg_match('/\bentity_extends\b/', $command)) { $constructor = file_get_contents('src/templates/entity_extends_constructor.template'); $baseExtends = 'extends'; } if (preg_match('/\bobject_base\b/', $command)) { $constructor = file_get_contents('src/templates/object_base_constructor.template'); } if (preg_match('/\bobject_extends\b/', $command)) { $constructor = file_get_contents('src/templates/object_extends_constructor.template'); $baseExtends = 'extends'; } if (preg_match('/\bbase\b/', $command)) { $constructor = file_get_contents('src/templates/base_constructor.template'); } if (preg_match('/\bextends\b/', $command)) { $constructor = file_get_contents('src/templates/extends_constructor.template'); $baseExtends = 'extends'; } if (!$constructor) { echo 'No constructor found for : ' . $file; return; } updateSection($file, $token , $constructor); } function extractOption($item, $template) { $item = trim($item); $matches = []; $key_value = preg_match('/^(\s*\w+)=(.*)$/', $item, $matches); if ($key_value === false) { return ''; } $key = $matches[1]; $value = $matches[2]; $comment_value = preg_split('/\s+-\s+/', $value); $comment = ''; if ($comment_value != false) { $value = $comment_value[0]; if (array_key_exists(1, $comment_value)) { $comment = $comment_value[1]; } else { $comment = 'No comment'; } $numSpaces = 1; $matches = []; $hasMultilineComment = preg_match('/\n^([ ]+)\*/sm', $template, $matches); if ($hasMultilineComment) { $str = $matches[1]; $numSpaces = strlen($str); } $comment = wordwrap($comment, 95, "\n" . str_pad('', $numSpaces, ' ', STR_PAD_LEFT) . "* "); } $updated = str_replace('COMMENT', $comment, $template); $updated = str_replace('KEY', $key, $updated); $updated = str_replace('VALUE', $value, $updated); return $updated; } function generateRequiredComponents($file, $tokens, $token, $section) { $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return; } $template = file_get_contents('src/templates/generated_required_components.template'); $updates = ''; foreach ($store as $item) { $updates .= extractOption($item, $template); } updateSection($file, $section , $updates); } function stripRequiredComponents(&$store, $tokens) { $excluded = getTokenStore('CUSTOM_REQUIRED_COMPONENTS', $tokens); if (sizeof($excluded) >= 0) { $newStore = []; $excludedIndexes = []; foreach ($excluded as $excludedItem) { $excludedItem = trim($excludedItem); $matches = []; $key_value = preg_match('/^(\s*\w+)=(.*)$/', $excludedItem, $matches); if ($key_value === false) { return ''; } $excludedKey = $matches[1]; for ($i = 0; $i < sizeof($store); $i++) { $item = trim($store[$i]); $matches = []; $key_value = preg_match('/^(\s*\w+)=(.*)$/', $item, $matches); if ($key_value === false) { continue; } $actualKey = $matches[1]; if ($actualKey === $excludedKey) { array_push($excludedIndexes, $i); } } } for ($i = 0; $i < sizeof($store); $i++) { if (!in_array($i, $excludedIndexes)){ array_push($newStore, $store[$i]); } } $store = $newStore; } } function generateInitOptions($file, $tokens, $token, $section) { $store = getTokenStore($token, $tokens); // stripRequiredComponents($store, $tokens); if (sizeof($store) <= 0) { return; } // echo "Will be building options for $token\n"; $template = file_get_contents('src/templates/generated_custom_options_init.template'); $updates = ''; foreach ($store as $item) { $updates .= extractOption($item, $template); } updateSection($file, $section , $updates); } function generateInitStaticOptions($file, $tokens, $token, $section) { $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return; } // echo "Will be building static options for $token\n"; $template = file_get_contents('src/templates/generated_custom_static_options_init.template'); $updates = ''; foreach ($store as $item) { $updates .= extractOption($item, $template); } updateSection($file, $section , $updates); } function getTokenStore($tokenName, $tokens) { if (is_array($tokens) && array_key_exists($tokenName, $tokens)) { return $tokens[$tokenName]; } return []; } function getInstanceMappings($tokens, $token) { $instanceMappings = []; foreach (getTokenStore($token, $tokens) as $mapping) { $mapping = trim($mapping); $key_value = preg_split('/=/', $mapping); if ($key_value === false) { continue; } $key = $key_value[0]; $value = $key_value[1]; $instanceMappings[$key] = $value; } return $instanceMappings; } function isExcluded($key, $tokens, $excludedToken) { if (array_key_exists($excludedToken, $tokens)) { $excluded = []; foreach ($tokens[$excludedToken] as $exclude) { array_push($excluded, trim($exclude)); } if (in_array($key, $excluded)) { return true; } } return false; } function doInstanceUpdate($template, $tokens, $token, $mappingToken, $excludedToken) { $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return null; } $instanceMappings = getInstanceMappings($tokens, $mappingToken); $updates = ''; foreach ($store as $item) { $item = trim($item); $key_value = preg_split('/=/', $item); if ($key_value === false) { continue; } $key = $key_value[0]; $value = $key_value[0]; if (array_key_exists($key, $instanceMappings)) { $value = $instanceMappings[$key]; } if (isExcluded($key, $tokens, $excludedToken)){ continue; } $updated = str_replace('INSTANCE_KEY', $value, $template); $updated = str_replace('KEY', $key, $updated); $updates .= $updated; } return $updates; } /** * Process updateInstance options */ function generateUpdateInstanceOptions($file, $tokens, $token, $section, $mappingToken, $excludedToken) { $template = file_get_contents('src/templates/generated_update_instance_options.template'); $updates = doInstanceUpdate($template, $tokens, $token, $mappingToken, $excludedToken); if ($updates) { // echo "Updating update instance options\n"; updateSection($file, $section, $updates); } else { // echo "No update instance options found to generate\n"; } } /** * Process updateFromInstance options */ function generateUpdateFromInstanceOptions($file, $tokens, $token, $section, $mappingToken, $excludedToken) { $template = file_get_contents('src/templates/generated_update_from_instance_options.template'); $updates = doInstanceUpdate($template, $tokens, $token, $mappingToken, $excludedToken); if ($updates) { // echo "Updating update from instance options\n"; updateSection($file, $section, $updates); } else { // echo "No update from instance options found to generate\n"; } } function getEventListenerInfo($item) { $item = trim($item); $eventName = preg_replace('/Event./', '', $item); $returns = null; $comment = null; $values = preg_split('/\s*-\s*/', $eventName); if (sizeof($values) > 1) { $eventName = $values[0]; $comment = $values[1]; } $values = preg_split('/@return[s]*\s*/', $comment); if (sizeof($values) > 1) { $comment = $values[0]; $returns = $values[1]; } $methodName = 'ON_'.$eventName; $methodTokenName = $methodName; $methodName = to_camel_case_from_upper_underscore($methodName); return [ 'eventName' => $eventName, 'fullEventName' => 'Event.'.$eventName, 'returns' => $returns, 'comment' => $comment, 'methodName' => $methodName, 'methodTokenName' => $methodTokenName ]; } function generateEventListenersStart($file, $tokens) { $token = 'CUSTOM_EVENT_LISTENERS'; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return; } echo "Will be building events for $file\n"; $template = file_get_contents('src/templates/generated_event_listeners_start.template'); $updated = ''; foreach ($store as $item) { $info = getEventListenerInfo($item); $updates = str_replace('FULL_EVENT_NAME', $info['fullEventName'], $template); $updates = str_replace('EVENT_NAME', $info['eventName'], $updates); $updates = str_replace('CALL_BACK', $info['methodName'], $updates); $updated .= $updates; } updateSection($file, 'GENERATED_EVENT_LISTENERS_START' , $updated); } function generateEventListenersStop($file, $tokens) { $token = 'CUSTOM_EVENT_LISTENERS'; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return; } echo "Will be events for $file\n"; $template = file_get_contents('src/templates/generated_event_listeners_stop.template'); $updated = ''; foreach ($store as $item) { $info = getEventListenerInfo($item); $updates = str_replace('EVENT_NAME', $info['eventName'], $template); $updated .= $updates; } updateSection($file, 'GENERATED_EVENT_LISTENERS_STOP' , $updated); } function generateStaticEventListenersStart($file, $tokens) { $token = 'CUSTOM_STATIC_EVENT_LISTENERS'; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return; } echo "Will be building events for $file\n"; $template = file_get_contents('src/templates/generated_static_event_listeners_start.template'); $updated = ''; foreach ($store as $item) { $info = getEventListenerInfo($item); $updates = str_replace('FULL_EVENT_NAME', $info['fullEventName'], $template); $updates = str_replace('EVENT_NAME', $info['eventName'], $updates); $updates = str_replace('CALL_BACK', $info['methodName'], $updates); $updated .= $updates; } updateSection($file, 'GENERATED_STATIC_EVENT_LISTENERS_START' , $updated); } function generateStaticEventListenersStop($file, $tokens) { $token = 'CUSTOM_STATIC_EVENT_LISTENERS'; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return; } echo "Will be events for $file\n"; $template = file_get_contents('src/templates/generated_static_event_listeners_stop.template'); $updated = ''; foreach ($store as $item) { $info = getEventListenerInfo($item); $updates = str_replace('EVENT_NAME', $info['eventName'], $template); $updated .= $updates; } updateSection($file, 'GENERATED_STATIC_EVENT_LISTENERS_STOP' , $updated); } /** * @param $item * @return array */ function getMethodDetails($item) { $item = trim($item); $methodName = $item; $matches = []; $result = preg_match('/^(.*?)\(/', $item, $matches); if ($result !== false && sizeof($matches) >= 2) { $methodName = $matches[1]; } $args = ''; $result = preg_match('/\((.*?)\)/', $item, $matches); if ($result !== false && sizeof($matches) >= 2) { $args = $matches[1]; } $argsArray = preg_split('/,(\s*)/', $args); $comment = 'No comment'; $result = preg_match('/.*?\).*?(\w.*$)/', $item, $matches); if ($result !== false && sizeof($matches) >= 2) { $comment = $matches[1]; } $returns = preg_split('/@return[s]*\s*/', $comment); if (sizeof($returns) > 1) { $comment = $returns[0]; $returns = $returns[1]; } else { $returns = null; } $methodTokenName = strtoupper(from_camel_case($methodName)); return [ 'methodName' => $methodName, 'methodTokenName' => $methodTokenName, 'args' => $args, 'argsArray' => $argsArray, 'comment' => $comment, 'returns' => $returns ]; } function getMethodTemplate($token, &$updated, $methodTokenName) { global $baseExtends; $staticNormal = ''; if ($token === 'CUSTOM_STATIC_METHODS' || $token === 'TEMPLATE_STATIC_METHODS') { $staticNormal = 'static_'; } $templateFound = false; /** * Do before function */ $potentialTemplate = strtolower('src/templates/' . $staticNormal . $baseExtends . '_' . $methodTokenName . '.template'); if (file_exists($potentialTemplate)) { $templateFound = true; } if (!$templateFound) { $potentialTemplate = strtolower('src/templates/' . $staticNormal . $methodTokenName . '.template'); } if (file_exists($potentialTemplate)) { $templateFound = true; } if ($templateFound) { $functionTemplate = file_get_contents($potentialTemplate); $updated = preg_replace('/^\s*\bFUNCTION_TEMPLATE\b/m', $functionTemplate, $updated); } else { $updated = preg_replace('/^.*?\bFUNCTION_TEMPLATE\b.*\n/m', '', $updated); } $templateFound = false; /** * Do after function */ $potentialTemplate = strtolower('src/templates/' . $staticNormal . $baseExtends . '_' . $methodTokenName . '_after.template'); if (file_exists($potentialTemplate)) { $templateFound = true; } if (!$templateFound) { $potentialTemplate = strtolower('src/templates/' . $staticNormal . $methodTokenName . '_after.template'); } if (file_exists($potentialTemplate)) { $templateFound = true; } if ($templateFound) { $functionTemplate = file_get_contents($potentialTemplate); $updated = preg_replace('/^\s*\bFUNCTION_TEMPLATE_AFTER\b/m', $functionTemplate, $updated); } else { $updated = preg_replace('/^.*?\bFUNCTION_TEMPLATE_AFTER\b.*\n/m', '', $updated); } } /** * @param $template * @param $tokens * @param $token * @return string|null */ function doMethodUpdate($template, $tokens, $token) { global $baseExtends; $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return null; } $updates = ''; foreach ($store as $item) { $detail = getMethodDetails($item); $argsArray = $detail['argsArray']; $args = $detail['args']; $methodTokenName = $detail['methodTokenName']; $methodName = $detail['methodName']; $comment = $detail['comment']; $returns = $detail['returns']; if (sizeof($argsArray) > 1) { $args = implode(",\n ", $argsArray); $args = "\n " . $args . "\n "; $params = implode("\n * @param ", $argsArray); $params = "\n * @param " . $params; } else if (sizeof($argsArray) === 1) { if ($args === '') { $params = $args; } else { $params = "\n * @param " . $args; } } if ($returns !== null) { $returns = "\n * @returns " . $returns; } $comment = wordwrap($comment, 110, "\n * "); $updated = $template; getMethodTemplate($token, $updated, $methodTokenName); $updated = str_replace('METHOD_ARGS', $args, $updated); $updated = str_replace('METHOD_NAME_UPPERCASE', $methodTokenName, $updated); $updated = str_replace('METHOD_NAME', $methodName, $updated); $updated = str_replace('COMMENT', $comment, $updated); $updated = str_replace('PARAMS', $params, $updated); $updated = str_replace('RETURNS', $returns, $updated); $updates .= $updated; } return $updates; } function generateStaticMethods($file, $tokens, $token, $section) { $template = file_get_contents('src/templates/generated_static_methods.template'); $updates = doMethodUpdate($template, $tokens, $token); if ($updates) { // echo "Updating static methods\n"; updateSection($file, $section, $updates); } else { // echo "No static methods found to generate\n"; } } function getEventListenerUpdates($template, $tokens, $token) { $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return null; } $updates = ''; foreach ($store as $item) { $item = trim($item); $eventName = preg_replace('/Event./', '', $item); $methodName = 'ON_'.$eventName; $methodTokenName = $methodName; $methodName = to_camel_case_from_upper_underscore($methodName); $updated = $template; $methodArgs = 'data'; $params = "\n * @param " . $methodArgs . " (The event data passed as argument - typically an R3Object)"; $returns = "\n * @return null"; $potentialTemplate = strtolower('src/templates/' . $methodTokenName . '.template'); if (file_exists($potentialTemplate)) { $functionTemplate = file_get_contents($potentialTemplate); $updated = preg_replace('/^\s*FUNCTION_TEMPLATE/m', $functionTemplate, $updated); } else { $updated = preg_replace('/^.*?FUNCTION_TEMPLATE.*\n/m', '', $updated); } $updated = str_replace('METHOD_NAME_UPPERCASE', $methodTokenName, $updated); $updated = str_replace('METHOD_NAME', $methodName, $updated); $updated = str_replace('METHOD_ARGS', $methodArgs, $updated); $comment = 'Listens to events of type ' . $item . ' and executes this function.'; $comment = wordwrap($comment, 110, "\n * "); $updated = str_replace('COMMENT', $comment, $updated); $updated = str_replace('PARAMS', $params, $updated); $updated = str_replace('RETURNS', $returns, $updated); $updates .= $updated; } return $updates; } function getStaticEventListenerUpdates($template, $tokens, $token) { $store = getTokenStore($token, $tokens); if (sizeof($store) <= 0) { return null; } $updates = ''; foreach ($store as $item) { $info = getEventListenerInfo($item); $updated = $template; $methodArgs = 'object'; $params = "\n * @param " . $methodArgs . " (The event data passed as argument - typically an R3Object)"; $returns = "\n * @return " . $info['returns']?:'null'; $potentialTemplate = strtolower('src/templates/static_' . $info['methodTokenName'] . '.template'); if (file_exists($potentialTemplate)) { $functionTemplate = file_get_contents($potentialTemplate); $updated = preg_replace('/^\s*FUNCTION_TEMPLATE/m', $functionTemplate, $updated); } else { $updated = preg_replace('/^.*?FUNCTION_TEMPLATE.*\n/m', '', $updated); } $updated = str_replace('METHOD_NAME_UPPERCASE', $info['methodTokenName'], $updated); $updated = str_replace('METHOD_NAME', $info['methodName'], $updated); $updated = str_replace('METHOD_ARGS', $methodArgs, $updated); $comment = 'Listens to events of type ' . $info['fullEventName'] . ' and executes this function. ' . $info['comment']; $comment = wordwrap($comment, 110, "\n * "); $returns = wordwrap($returns, 110, "\n * "); $updated = str_replace('COMMENT', $comment, $updated); $updated = str_replace('PARAMS', $params, $updated); $updated = str_replace('RETURNS', $returns, $updated); $updates .= $updated; } return $updates; } function generateEventListenerMethods($file, $tokens) { $token = 'CUSTOM_EVENT_LISTENERS'; $template = file_get_contents('src/templates/generated_methods.template'); $updates = getEventListenerUpdates($template, $tokens, $token); if ($updates) { // echo "Updating event listeners.. \n"; updateSection($file, 'GENERATED_EVENT_LISTENER_METHODS', $updates); } else { // echo "No event listeners found to generate\n"; } } function generateStaticEventListenerMethods($file, $tokens) { $token = 'CUSTOM_STATIC_EVENT_LISTENERS'; $template = file_get_contents('src/templates/generated_static_methods.template'); $updates = getStaticEventListenerUpdates($template, $tokens, $token); if ($updates) { // echo "Updating static event listeners.. \n"; updateSection($file, 'GENERATED_STATIC_EVENT_LISTENER_METHODS', $updates); } else { // echo "No static event listeners found to generate\n"; } } function generateImports($file, $tokens, $command) { $updates = []; if ( array_key_exists('CUSTOM_REQUIRED_COMPONENTS', $tokens) && sizeof($tokens['CUSTOM_REQUIRED_COMPONENTS']) > 0 ) { array_push($updates, "const Event = require('../r3-event.js');\n"); } if ( array_key_exists('TEMPLATE_METHODS', $tokens) && sizeof($tokens['TEMPLATE_METHODS']) > 0 ) { foreach ($tokens['TEMPLATE_METHODS'] as $method) { if (preg_match('/initialize\(\)/', $method)) { if (!preg_match('/ Component/', $command)) { array_push($updates, "const Component = require('../r3-component/r3-component.js');\n"); } if (!preg_match('/ Entity /', $command)) { array_push($updates, "const Entity = require('../r3-entity/r3-entity.js');\n"); } } } } if (sizeof($updates) === 0) { return; } updateSection($file, 'GENERATED_IMPORTS', $updates); } function generateMethods($file, $tokens, $token, $section) { $template = file_get_contents('src/templates/generated_methods.template'); $updates = doMethodUpdate($template, $tokens, $token); if ($updates) { updateSection($file, $section, $updates); } else { // echo "No methods found to generate\n"; } } function buildImportsAndBody(&$imports, &$body, &$tests, &$testImports, $node, $type, $nameSpace) { $originalNameSpace = $nameSpace; foreach ($node->children as $child) { $nameSpace = $originalNameSpace . '.' . $child->nameSpaceClassName; $file = str_replace('src/r3/r3-' . str_replace('r3-', '', strtolower(from_camel_case($type,'-'))), '.', $child->file); $important = true; if (preg_match('/src\/r3/', $file)) { $important = false; $file = preg_replace('/src\/r3/','..',$file); } array_push($imports, "const " . $child->name . ' = require(\'' . $file . "');"); array_push($body, "$nameSpace = " . $child->name . ';'); if ($important) { array_push($testImports, "const " . $child->name . ' = require(\'../src/r3/r3-' . str_replace('r3object','object', strtolower($type)) . '/' . $file . "');"); array_push($tests, "\t\t\tconst " . lcfirst($child->name) . " = new " . $child->name . '();'); } $child->nameSpace = $nameSpace; buildImportsAndBody($imports, $body, $tests, $testImports, $child, $type, $nameSpace); } } function generateIndex($types) { /** * Graph $graph */ global $graph; $template = file_get_contents('src/templates/index.template'); foreach ($types as $type) { $imports = []; $testImports = []; $body = []; $exports = []; $tests = []; $nodes = $graph->walk(); foreach ($nodes as $node) { if (preg_match("/\b$type\b/", $node->name)) { $file = str_replace('src/r3/r3-' . str_replace('r3-', '', strtolower(from_camel_case($type,'-'))), '.', $node->file); array_push($imports, "const " . $node->name . ' = require(\'' . $file . "');"); buildImportsAndBody($imports, $body, $tests, $testImports,$node, $type, $type); } } array_push($exports, "module.exports = $type;"); $indexFile = 'src/r3/r3-'. str_replace('r3-', '', strtolower(from_camel_case($type,'-'))) . '/index.js'; file_put_contents($indexFile, $template); updateSection($indexFile, 'GENERATED_IMPORTS', implode("\n", $imports)); updateSection($indexFile, 'GENERATED_INDEX_BODY', implode("\n", $body)); updateSection($indexFile, 'GENERATED_EXPORTS', implode("\n", $exports)); $testFile = 'test/R3.test.js'; updateSection($testFile, 'GENERATED_' . to_upper_underscore($type) . '_CREATE', implode("\n", $tests)); updateSection($testFile, 'GENERATED_' . to_upper_underscore($type) . '_IMPORTS', implode("\n", $testImports)); } } function generateR3($nodes, $graph) { $imports = []; $defines = []; $modifiedPaths = [ '/\br3-component.js$/', '/\br3-entity.js$/', '/\br3-object.js$/', '/\br3-runtime.js$/', '/\br3-system.js$/' ]; foreach ($nodes as $node) { if ( $node->parent === null || $node->parent->parent === null || //i.e. is a base class $node->parent->name === 'Event' || //i.e. extends Event directly $node->parent->name === 'R3Object' //i.e. extends Object directly ) { $file = str_replace('src/r3', '.', $node->file); foreach ($modifiedPaths as $modifiedPath) { $file = preg_replace($modifiedPath, '', $file); } array_push($imports, "const " . $node->name . " = require('" . $file . "');"); if ($node->parent !== null) { array_push($defines, 'R3.' . $node->nameSpaceClassName . ' = ' . $node->name); } } } $component = $graph->search('name', 'Component'); $children = $graph->flatten($component); foreach ($children as $child) { if (sizeof($child->children) === 0) { array_push($defines, 'R3.' . $child->nameSpaceClassName . ' = ' . $child->nameSpace); } } $r3Index = 'src/r3/index.js'; save($r3Index, getTokens(['CUSTOM'])); $tokens = loadSaved($r3Index . '.saved', getTokens(['CUSTOM'])); $template = file_get_contents('src/templates/r3_index.template'); file_put_contents($r3Index, $template); deleteSavedFile($r3Index . '.saved'); $version = file_get_contents('version'); $packageJson = file_get_contents('package.json'); $packageJson = preg_replace('/(.*version.*: ").*(".*)/', '${1}' . $version . '${2}', $packageJson); file_put_contents('package.json', $packageJson); $r3js = 'src/r3/r3.js'; $contents = file_get_contents($r3js); $contents = str_replace(' = \'__COMPILE_DATE__\'', ' = \'' . date("Y M d - H:i:s a") . '\'', $contents); $contents = str_replace(' = \'__VERSION__\'', ' = \'' . $version . '\'', $contents); file_put_contents($r3js, $contents); $exports = 'module.exports = R3;'; $systemBody = []; foreach ($nodes as $node) { /** * Node $node */ if (preg_match('/\bSystem\w+\b/', $node->name)){ array_push($systemBody, 'R3.' . $node->nameSpace . ".Start();"); } } if (in_array('CUSTOM_DEFINES', array_keys($tokens))) { updateSection($r3Index, 'CUSTOM_DEFINES', $tokens['CUSTOM_DEFINES']); } updateSection($r3Index, 'GENERATED_IMPORTS', implode("\n", $imports)); updateSection($r3Index, 'GENERATED_DEFINES', implode(";\n", $defines) . ";"); updateSection($r3Index, 'GENERATED_SYSTEM', implode("\n", $systemBody)); updateSection($r3Index, 'GENERATED_EXPORTS', $exports); } function generateEvents() { echo "Generating Events\n"; global $files; $events = []; foreach ($files as $file) { // $file = './src/r3/' . $file; // echo $file . "\n"; // continue; if ( preg_match('/\.js$/', $file) && !preg_match('/r3\-event/', $file) ) { // echo "processing file " . $file . "\n"; $fn = fopen($file, "r"); while (!feof($fn)) { $line = fgets($fn); $matches = []; $eventMatchRegex = '/Event\.[A-Z]{2}[A-Z0-9_]+/'; if ( preg_match($eventMatchRegex, $line) && preg_match_all($eventMatchRegex, $line, $matches) && $matches[0] && $matches[0][0] ) { $event = $matches[0][0]; if (in_array($event, $events)) { // Do nothing } else { array_push($events, $event); } } } fclose($fn); } } array_push($events, 'Event.START'); array_push($events, 'Event.PAUSE'); array_push($events, 'Event.RESTART'); sort($events); $i = 1; $eventList = ''; $eventFunction = "Event.GetEventName = function(eventId) {\n\n\tswitch(eventId) {\n"; foreach ($events as $event) { $eventList .= $event . " = " . "0x" . dechex($i) . ";\n"; $eventFunction .= "\t\tcase 0x" . dechex($i). " : return '" . strtolower(str_replace('Event.', '', $event)) . "';\n"; $i++; } $eventList .= "Event.MAX_EVENTS = " . "0x" . dechex($i) . ";\n\n"; $eventFunction .= "\t\tdefault :\n\t\t\tthrow new Error('Event type not defined : ' + eventId);\n"; $eventFunction .= "\t}\n\n"; $eventFunction .= "};\n"; // echo $eventList; // echo $eventFunction; updateSection('./src/r3/r3-event.js', 'GENERATED_EVENTS' , $eventList . $eventFunction); } function getSource($node, &$source) { $contents = file_get_contents($node->file); array_push($source, $contents); foreach ($node->children as $child) { getSource($child, $source); } } function buildDefines(&$defines, $node, $nameSpace) { $originalNameSpace = $nameSpace; foreach ($node->children as $child) { $nameSpace = $originalNameSpace . '.' . $child->nameSpaceClassName; array_push($defines, $nameSpace. ' = ' . $child->nameSpaceClassName); buildDefines($defines, $child, $nameSpace); } } function generateR3Dist($nodes) { global $graph; $r3jsDist = 'dist/r3.js'; $r3IndexTemplate = 'src/templates/r3_index.template'; $r3jsIndex = 'src/r3/index.js'; $template = file_get_contents($r3IndexTemplate); file_put_contents($r3jsDist, $template); $r3 = $graph->search('name', 'R3'); $source = []; getSource($r3,$source); updateSection($r3jsDist, 'GENERATED_SOURCE', $source); $r3jsDistPointer = fopen($r3jsDist, "a"); $generateTokens = getTokens(['GENERATED']); $customTokens = getTokens(['CUSTOM']); $indexFiles = [ 'src/r3/r3-component/index.js', 'src/r3/r3-entity/index.js', 'src/r3/r3-object/index.js', 'src/r3/r3-runtime/index.js', 'src/r3/r3-system/index.js', ]; foreach ($indexFiles as $indexFile) { $savedGenerate = save($indexFile, $generateTokens)[1]; foreach ($savedGenerate as $key => $store) { if ($key != 'GENERATED_INDEX_BODY') { continue; } foreach ($store as $line) { fwrite($r3jsDistPointer, $line); } } deleteSavedFile($indexFile . '.saved'); } $savedGenerate = save($r3jsIndex, $generateTokens)[1]; $savedCustom = save($r3jsIndex, $customTokens)[1]; foreach ($savedGenerate as $key => $store) { if ($key === 'GENERATED_IMPORTS') { continue; } foreach ($store as $line) { fwrite($r3jsDistPointer, $line); } } foreach ($savedCustom as $key => $store) { foreach ($store as $line) { fwrite($r3jsDistPointer, $line); } } fclose($r3jsDistPointer); deleteSavedFile($r3jsIndex . '.saved'); /** * Now start cleaning up the file */ $contents = file_get_contents($r3jsDist); $tokensForRemoval = [ 'GENERATED_IMPORTS', 'GENERATED_EXPORTS', 'TEMPLATE_OPTIONS', 'CUSTOM_OPTIONS', 'TEMPLATE_STATIC_OPTIONS', 'CUSTOM_STATIC_OPTIONS', 'TEMPLATE_INSTANCE_OPTIONS_MAPPING', 'CUSTOM_INSTANCE_OPTIONS_MAPPING', 'TEMPLATE_EXCLUDED_FROM_INSTANCE_OPTIONS', 'CUSTOM_EXCLUDED_FROM_INSTANCE_OPTIONS', 'TEMPLATE_METHODS', 'CUSTOM_METHODS', 'TEMPLATE_STATIC_METHODS', 'CUSTOM_STATIC_METHODS', 'CUSTOM_EVENT_LISTENERS', 'CUSTOM_STATIC_EVENT_LISTENERS' ]; foreach ($tokensForRemoval as $tokenForRemoval) { $contents = preg_replace('/\n^[\/\s]*?\b'.$tokenForRemoval.'_START\b.*?\b'.$tokenForRemoval.'_END.*?$/sm', '', $contents); } $contents = preg_replace('/\n^\bmodule\.exports\s+=\s+{.*?}$/sm', '', $contents); $contents = preg_replace('/\n^\bmodule\.exports\s+=.*?$/sm', '', $contents); $contents = preg_replace('/\n^\bconst.*?= require.*?$/sm', '', $contents); foreach ($generateTokens as $generateTokenKey => $generateTokenValue) { /** * Remove generate tokens */ $contents = preg_replace('/.*\b' . $generateTokenKey . '(_START|_END)\b.*?\n/m', '', $contents ); } foreach ($customTokens as $customTokenKey => $customTokenValue) { /** * Remove generate tokens */ $contents = preg_replace('/.*\b' . $customTokenKey . '(_START|_END)\b.*?\n/m', '', $contents ); } $contents = preg_replace('/\n^\/\*\*\s+\*\*\/\s*?$/sm', '', $contents); $contents = preg_replace('/\n\n\n+/sm', "\n\n", $contents); $contents = str_replace('__API_URL__', $_ENV['API_URL'], $contents); file_put_contents($r3jsDist, $contents); } function updateParentSystems($nodes) { foreach ($nodes as $node) { $className = $node->name; if ($node->parent === null) { $contents = file_get_contents($node->file); $contents = preg_replace('/CLASS_NAME/', $className, $contents); file_put_contents($node->file, $contents); continue; } $parentName = $node->parent->name; if ($node->parent->parent === null) { /** * We are working with the base system class */ $parentName = $node->name; } $contents = file_get_contents($node->file); $contents = preg_replace('/PARENT_SYSTEM/', $parentName, $contents); $contents = preg_replace('/CLASS_NAME/', $className, $contents); $contents = preg_replace('/SYSTEM_NAME/', $className, $contents); file_put_contents($node->file, $contents); } } function buildNodeList($file) { // echo "loading file $file\n"; global $nodeList; $fn = fopen($file, "r"); $line = ''; $found = false; while (!feof($fn) && !$found) { $line = fgets($fn); if (preg_match('/^class\s+/', $line)) { $found = true; break; } } if ($found) { // echo $line . "\n"; $matches = []; $result = preg_match('/^class\s+(.*?)(\s+extends\s+(.*?)\s+|\s+?{)/', $line, $matches); if ($result === false) { throw new ErrorException('Could not match'); } $extends = null; if (sizeof($matches) === 4) { $class = $matches[1]; $extends = $matches[3]; } else if (sizeof($matches) === 3) { $class = $matches[1]; } else { throw new ErrorException('Unhandled case'); } $nameSpace = ''; $nameSpaceClassName = $class; $needles = [ 'Component', 'Entity', 'Runtime', 'System' ]; $isBaseClass = true; if ($extends) { $isBaseClass = false; $nameSpaceClassName = str_replace($extends, '', $class); foreach ($needles as $needle) { if ($needle != $nameSpaceClassName) { $nameSpaceClassName = str_replace($needle, '', $nameSpaceClassName); } } $nameSpaceClassName = str_replace('R3', '', $nameSpaceClassName); } $node = new Node( $file, $class, $nameSpace, $nameSpaceClassName, $extends, [], $isBaseClass ); array_push($nodeList, $node); } else { echo "not found\n"; } fclose($fn); } function generateOutOfClassImplementationDefines($graph, $types) { foreach ($types as $type) { if ($type === 'Runtime') { $i = 0; $nodes = $graph->walk(); foreach ($nodes as $node) { if (preg_match('/\bRuntime\b/', $node->name) && $node->isBaseClass) { $parent = $node; $updateList = []; foreach ($parent->children as $child) { array_push($updateList, 'Runtime.' . strtoupper(from_camel_case(str_replace('Runtime','Base', $child->name))) . ' = 0x' . dechex($i) . ";\n"); $i++; } foreach ($parent->children as $child) { foreach ($child->children as $implementation) { array_push($updateList, 'Runtime.' . strtoupper(from_camel_case(str_replace('Runtime', '', $implementation->name))) . ' = 0x' . dechex($i) . ";\n"); $i++; } } updateSection($parent->file, 'GENERATED_OUT_OF_CLASS_IMPLEMENTATION' , $updateList); } } } else { $i = 0; $updateList = []; $parent = $graph->search('name', $type); $children = $graph->flatten($parent); foreach ($children as $child) { array_push($updateList, $parent->name . '.' . strtoupper(from_camel_case(str_replace($parent->name, '', $child->name))) . ' = 0x' . dechex($i) . ";\n"); $i++; } array_push($updateList, $parent->name . '.MAX_' . strtoupper($parent->name) . ' = 0x' . dechex($i) . ";\n"); updateSection($parent->file, 'GENERATED_OUT_OF_CLASS_IMPLEMENTATION' , $updateList); } } } //function generateRuntimes() //{ // // updateSection( // 'src/r3/r3-runtime.js', // 'GENERATED_RUNTIMES', // [ // 'Runtime.RUNTIME_DEFAULT' // ] // ); // //} $nodeList = []; /** * @throws ErrorException */ foreach ($files as $file) { $saveFile = null; if ($argv[2] == 'save') { $saveFile = $file . '.saved'; if (file_exists($saveFile)) { echo "A previous restore operation did not complete - please remove the saved file before trying this again\n"; echo "The save file is located at $saveFile\n"; echo "Remove easily with:\n"; echo "rm $saveFile\n"; exit(0); } $tokens = getTokens(['CUSTOM']); $result = save($file, $tokens); exit(1); } else if ($argv[2] == 'restore') { $saveFile = $file . '.saved'; $restoreTokens = getTokens(['CUSTOM']); $restoreTokenKeys = array_keys($restoreTokens); try { $tokens = loadSaved($file . '.saved', $restoreTokens); } catch (ErrorException $e) { echo $e->getMessage(); exit(0); } $templateTokens = getTokens(['TEMPLATE']); try { $tokenData = loadSaved($file, $templateTokens, true); } catch (ErrorException $e) { echo $e->getMessage(); exit(0); } $tokens = array_merge($tokens, $tokenData); $skipped = []; foreach ($tokens as $token => $store) { if (in_array($token, $restoreTokenKeys)) { updateSection($file, $token, $store); } } echo "Generating Constructors\n"; generateConstructors($file, $argv[3]); echo "Generating Methods\n"; generateImports($file, $tokens, $argv[3]); generateMethods($file, $tokens, 'TEMPLATE_METHODS', 'GENERATED_TEMPLATE_METHODS'); generateMethods($file, $tokens, 'CUSTOM_METHODS', 'GENERATED_METHODS'); generateStaticMethods($file, $tokens, 'CUSTOM_STATIC_METHODS', 'GENERATED_STATIC_METHODS'); generateStaticMethods($file, $tokens, 'TEMPLATE_STATIC_METHODS', 'GENERATED_TEMPLATE_STATIC_METHODS'); generateEventListenerMethods($file, $tokens); generateStaticEventListenerMethods($file, $tokens); echo "Generating Options\n"; generateInitOptions($file, $tokens, 'TEMPLATE_OPTIONS', 'GENERATED_TEMPLATE_OPTIONS_INIT'); generateInitOptions($file, $tokens, 'CUSTOM_OPTIONS', 'GENERATED_OPTIONS_INIT'); generateInitStaticOptions($file, $tokens, 'CUSTOM_STATIC_OPTIONS', 'GENERATED_STATIC_OPTIONS_INIT'); generateInitStaticOptions($file, $tokens, 'TEMPLATE_STATIC_OPTIONS', 'GENERATED_TEMPLATE_STATIC_OPTIONS_INIT'); generateRequiredComponents($file, $tokens, 'CUSTOM_REQUIRED_COMPONENTS', 'GENERATED_REQUIRED_COMPONENTS'); // generateCreateInstanceOptions($file, $tokens); generateUpdateInstanceOptions($file, $tokens, 'CUSTOM_OPTIONS', 'GENERATED_UPDATE_INSTANCE_OPTIONS', 'CUSTOM_INSTANCE_OPTIONS_MAPPING', 'CUSTOM_EXCLUDED_FROM_INSTANCE_OPTIONS'); generateUpdateInstanceOptions($file, $tokens, 'TEMPLATE_OPTIONS', 'GENERATED_TEMPLATE_UPDATE_INSTANCE_OPTIONS', 'TEMPLATE_INSTANCE_OPTIONS_MAPPING', 'TEMPLATE_EXCLUDED_FROM_INSTANCE_OPTIONS'); generateUpdateFromInstanceOptions($file, $tokens, 'CUSTOM_OPTIONS', 'GENERATED_UPDATE_FROM_INSTANCE_OPTIONS', 'CUSTOM_INSTANCE_OPTIONS_MAPPING', 'CUSTOM_EXCLUDED_FROM_INSTANCE_OPTIONS'); generateUpdateFromInstanceOptions($file, $tokens, 'TEMPLATE_OPTIONS', 'GENERATED_TEMPLATE_UPDATE_FROM_INSTANCE_OPTIONS', 'TEMPLATE_INSTANCE_OPTIONS_MAPPING', 'TEMPLATE_EXCLUDED_FROM_INSTANCE_OPTIONS'); echo "Generating Event Listeners\n"; generateEventListenersStart($file, $tokens); generateEventListenersStop($file, $tokens); generateStaticEventListenersStart($file, $tokens); generateStaticEventListenersStop($file, $tokens); /** * Try to restore the rest of the old data because now methods were generated. * If not all data restores now - a method name / token has changed and we need * to notify the user */ foreach ($tokens as $token => $store) { if (in_array($token, $restoreTokenKeys)) { $result = updateSection($file, $token, $store); if ($result !== true && $result !== false) { array_push($skipped, $result); } } } if (sizeof($skipped) !== 0) { echo "Some tokens could not be restored because they could not be found in the new version\n"; print_r($skipped); echo "Please restore them manually from the saved file :$saveFile\n"; echo "If you do not do it now - on the next template update code will be overwritten and you could lose code!!!\n"; exit(0); } else { deleteSavedFile($saveFile); exit(1); } } else if ($argv[2] == 'build-dist') { buildNodeList($file); } } if ($argv[2] == 'generate-events') { generateEvents(); } if ($argv[2] == 'build-dist') { global $nodeList; /** * Now generate the graph based on the new classes */ $graph = new Graph( $nodeList ); $restoreTokens = getTokens(['CUSTOM']); $restoreTokenKeys = array_keys($restoreTokens); /** * Now start processing the files again - this time generating linked objects / inherited properties / methods */ foreach ($files as $file) { generateInherited($file, $restoreTokens); } generateIndex( [ 'Component', 'Entity', 'R3Object', 'Runtime', 'System', ] ); $nodes = $graph->walk(); // // Remove R3 (first node) from the list // array_shift($nodes); updateParentSystems($nodes); generateOutOfClassImplementationDefines( $graph, [ 'Component', 'Entity', 'R3Object', 'Runtime', 'System', ] ); echo "Building Distribution\n"; generateR3($nodes, $graph); generateR3Dist($nodes); foreach ($files as $file) { $saveFile = $file . '.saved'; deleteSavedFile($saveFile); } } exit(1); ?>