9 Ревизии

Автор SHA1 Съобщение Дата
  Ray 64921e2d8a
Merge pull request #5086 from maiconpintoabreu/ignore-compiled-rexm преди 3 седмици
  Maicon Santana 81eb48cad8 Add compiled rexm to gitignore преди 3 седмици
  Ray f306685469 Update rexm.c преди 3 седмици
  Ray 99a43457e8 REXM: ADDED: Command; `update` to validate+update required files преди 3 седмици
  Ray 90cf6a18da REXM: Renamed some variables преди 3 седмици
  Ray 1f2b5d6282 Update examples_template.c преди 3 седмици
  Ray 7b93591676 Added some notes to avoid platform-dependant .BAT scripts преди 3 седмици
  Ray 02992ce63b UPDATE: Get example info from example header when added, to be added to collection преди 3 седмици
  Ray b683af298c Update examples_template.c преди 3 седмици
променени са 3 файла, в които са добавени 147 реда и са изтрити 65 реда
  1. +1
    -0
      .gitignore
  2. +4
    -4
      examples/examples_template.c
  3. +142
    -61
      tools/rexm/rexm.c

+ 1
- 0
.gitignore Целия файл

@ -114,3 +114,4 @@ docgen_tmp/
# Tools stuff
tools/parser/raylib_parser
tools/rexm/VS2022
tools/rexm/rexm

+ 4
- 4
examples/examples_template.c Целия файл

@ -58,16 +58,16 @@
*
* raylib [<module>] example - <name>
*
* Example complexity rating: [o">??] ?/4
* Example complexity rating: [err">☆] 1/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed by <user_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5)
* Example contributed by <author_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) <year_created>-<year_updated> <user_name> (@<user_github>)
* Copyright (c) <year_created>-<year_updated> <author_name> (@<user_github>)
*
********************************************************************************************/

+ 142
- 61
tools/rexm/rexm.c Целия файл

@ -8,6 +8,7 @@
* - rename <old_examples_name> <new_example_name>
* - remove <example_name>
* - validate
* - update
*
* Files involved in the processes:
* - raylib/examples/<category>/<category>_example_name.c
@ -58,9 +59,12 @@
#define LOG(...)
#endif
#define REXM_MAX_BUFFER_SIZE (2*1024*1024) // 2MB
#define REXM_MAX_EXAMPLES 512
#define REXM_MAX_EXAMPLE_CATEGORIES 8
#define REXM_MAX_RESOURCE_PATHS 256
#define REXM_MAX_BUFFER_SIZE (2*1024*1024) // 2MB
#define REXM_MAX_RESOURCE_PATHS 256
//----------------------------------------------------------------------------------
// Types and Structures Definition
@ -78,17 +82,16 @@ typedef struct {
// Example management operations
typedef enum {
OP_NONE = 0, // No process to do
OP_CREATE = 1, // Create new example, using default template
OP_ADD = 2, // Add existing examples (hopefully following template)
OP_RENAME = 3, // Rename existing example
OP_REMOVE = 4, // Remove existing example
OP_VALIDATE = 5, // Validate examples, using [examples_list.txt] as main source by default
OP_NONE = 0, // No process to do
OP_CREATE = 1, // Create new example, using default template
OP_ADD = 2, // Add existing examples (hopefully following template)
OP_RENAME = 3, // Rename existing example
OP_REMOVE = 4, // Remove existing example
OP_VALIDATE = 5, // Validate examples, using [examples_list.txt] as main source by default
OP_UPDATE = 6, // Validate and update required examples (as far as possible)
} rlExampleOperation;
#define MAX_EXAMPLE_CATEGORIES 8
static const char *exCategories[MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio", "others" };
static const char *exCategories[REXM_MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio", "others" };
// Paths required for examples management
// TODO: Avoid hardcoding path values...
@ -178,7 +181,7 @@ int main(int argc, char *argv[])
char cat[12] = { 0 };
strncpy(cat, argv[2], catIndex);
bool catFound = false;
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{
if (TextIsEqual(cat, exCategories[i])) { catFound = true; break; }
}
@ -212,7 +215,7 @@ int main(int argc, char *argv[])
char cat[12] = { 0 };
strncpy(cat, argv[2], catIndex);
bool catFound = false;
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{
if (TextIsEqual(cat, exCategories[i])) { catFound = true; break; }
}
@ -274,16 +277,23 @@ int main(int argc, char *argv[])
}
else if (strcmp(argv[1], "validate") == 0)
{
// Validate examples in collection
// All examples in collection match all requirements on required files
// Validate examples in collection (report results)
// All examples in collection match all files requirements
opCode = OP_VALIDATE;
}
else if (strcmp(argv[1], "update") == 0)
{
// Validate and update examples in collection
// All examples in collection match all files requirements
opCode = OP_UPDATE;
}
}
switch (opCode)
{
case 1: // Create: New example from template
case nl">OP_CREATE: // Create: New example from template
{
// Create: raylib/examples/<category>/<category>_example_name.c
char *exText = LoadFileText(exTemplateFilePath);
@ -302,7 +312,7 @@ int main(int argc, char *argv[])
for (int i = 0; i < 6; i++) { MemFree(exTextUpdated[i]); exTextUpdated[i] = NULL; }
UnloadFileText(exText);
}
case mi">2: // Add: Example from command-line input filename
case nl">OP_ADD: // Add: Example from command-line input filename
{
// Add: raylib/examples/<category>/<category>_example_name.c
if (opCode != 1) FileCopy(inFileName, TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
@ -376,48 +386,102 @@ int main(int argc, char *argv[])
// Add example to the collection list, if not already there
// NOTE: Required format: shapes;shapes_basic_shapes;;1.0;4.2;"Ray";@raysan5
//------------------------------------------------------------------------------------------------
char *exColInfo = LoadFileText(exCollectionFilePath);
if (TextFindIndex(exColInfo, exName) == -1) // Example not found
char *exCollectionList = LoadFileText(exCollectionFilePath);
if (TextFindIndex(exCollectionList, exName) == -1) // Example not found
{
char *exColInfoUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated list copy, 2MB
char *exCollectionListUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated list copy, 2MB
// Add example to the main list, by category
// by default add it last in the category list
// NOTE: When populating to other files, lists are sorted by name
int nextCatIndex = 0;
if (strcmp(exCategory, "core") == 0) nextCatIndex = 1;
else if (strcmp(exCategory, "shapes") == 0) nextCatIndex = 2;
else if (strcmp(exCategory, "textures") == 0) nextCatIndex = 3;
else if (strcmp(exCategory, "text") == 0) nextCatIndex = 4;
else if (strcmp(exCategory, "models") == 0) nextCatIndex = 5;
else if (strcmp(exCategory, "shaders") == 0) nextCatIndex = 6;
else if (strcmp(exCategory, "audio") == 0) nextCatIndex = 7;
else if (strcmp(exCategory, "others") == 0) nextCatIndex = -1; // Add to EOF
// l">TODO: Get required example info from example file header (if provided)
int nextCategoryIndex = 0;
if (strcmp(exCategory, "core") == 0) nextCategoryIndex = 1;
else if (strcmp(exCategory, "shapes") == 0) nextCategoryIndex = 2;
else if (strcmp(exCategory, "textures") == 0) nextCategoryIndex = 3;
else if (strcmp(exCategory, "text") == 0) nextCategoryIndex = 4;
else if (strcmp(exCategory, "models") == 0) nextCategoryIndex = 5;
else if (strcmp(exCategory, "shaders") == 0) nextCategoryIndex = 6;
else if (strcmp(exCategory, "audio") == 0) nextCategoryIndex = 7;
else if (strcmp(exCategory, "others") == 0) nextCategoryIndex = -1; // Add to EOF
// Get required example info from example file header (if provided)
// NOTE: If no example info is provided (other than category/name), just using some default values
char *exText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
rlExampleInfo exInfo = { 0 };
strcpy(exInfo.category, exCategory);
strcpy(exInfo.name, exName);
if (nextCatIndex == -1)
// Get example difficulty stars
char starsText[16] = { 0 };
int starsIndex = TextFindIndex(exText, "");
if (starsIndex > 0) strncpy(starsText, exText + starsIndex, 3*4); // NOTE: Every UTF-8 star are 3 bytes
else strcpy(starsText, "★☆☆☆");
// Get example create with raylib version
char verCreateText[4] = { 0 };
int verCreateIndex = TextFindIndex(exText, "created with raylib "); // Version = index + 20
if (verCreateIndex > 0) strncpy(verCreateText, exText + verCreateIndex + 20, 3);
else strncpy(verCreateText, RAYLIB_VERSION, 3); // Only pick MAJOR.MINOR
// Get example update with raylib version
char verUpdateText[4] = { 0 };
int verUpdateIndex = TextFindIndex(exText, "updated with raylib "); // Version = index + 20
if (verUpdateIndex > 0) strncpy(verUpdateText, exText + verUpdateIndex + 20, 3);
else strncpy(verUpdateText, RAYLIB_VERSION, 3); // Only pick MAJOR.MINOR
// Get example creator and github user
int authorIndex = TextFindIndex(exText, "Example contributed by "); // Author = index + 23
int authorGitIndex = TextFindIndex(exText, "(@"); // Author GitHub user = index + 2
if (authorIndex > 0)
{
int authorNameLen = 0;
if (authorGitIndex > 0) authorNameLen = (authorGitIndex - 1) - (authorIndex + 23);
else
{
int authorNameEndIndex = TextFindIndex(exText + authorIndex, " and reviewed by Ramon Santamaria");
if (authorNameEndIndex == -1) authorNameEndIndex = TextFindIndex(exText + authorIndex, "\n");
authorNameLen = authorNameEndIndex - (authorIndex + 23);
}
strncpy(exInfo.author, exText + authorIndex + 23, authorNameLen);
}
else strcpy(exInfo.author, "<author_name>");
if (authorGitIndex > 0)
{
int authorGitEndIndex = TextFindIndex(exText + authorGitIndex, ")");
if (authorGitEndIndex > 0) strncpy(exInfo.authorGitHub, exText + authorGitIndex + 2, authorGitEndIndex - (authorGitIndex + 2));
}
else strcpy(exInfo.author, "<user_github>");
// TODO: Verify copyright line
// Copyright (c) <year_created>-<year_updated> <user_name> (@<user_github>)
UnloadFileText(exText);
if (nextCategoryIndex == -1)
{
// Add example to collection at the EOF
int endIndex = (int)strlen(exColInfo);
memcpy(exColInfoUpdated, exColInfo, endIndex);
sprintf(exColInfoUpdated + endIndex, TextFormat("%s;%s;⭐️☆☆☆;6.0;6.0;\"Ray\";@raysan5\n", exCategory, exName));
int endIndex = (int)strlen(exCollectionList);
memcpy(exCollectionListUpdated, exCollectionList, endIndex);
sprintf(exCollectionListUpdated + endIndex, TextFormat("%s;%s;%s;%s;%s;\"%s\";@%s\n",
exInfo.category, exInfo.name, starsText, verCreateText, verUpdateText, exInfo.author, exInfo.authorGitHub));
}
else
{
// Add example to collection, at the end of the category list
int catIndex = TextFindIndex(exColInfo, exCategories[nextCatIndex]);
memcpy(exColInfoUpdated, exColInfo, catIndex);
int textWritenSize = sprintf(exColInfoUpdated + catIndex, TextFormat("%s;%s;⭐️☆☆☆;6.0;6.0;\"Ray\";@raysan5\n", exCategory, exName));
memcpy(exColInfoUpdated + catIndex + textWritenSize, exColInfo + catIndex, strlen(exColInfo) - catIndex);
int categoryIndex = TextFindIndex(exCollectionList, exCategories[nextCategoryIndex]);
memcpy(exCollectionListUpdated, exCollectionList, categoryIndex);
int textWritenSize = sprintf(exCollectionListUpdated + categoryIndex, TextFormat("%s;%s;%s;%s;%s;\"%s\";@%s\n",
exInfo.category, exInfo.name, starsText, verCreateText, verUpdateText, exInfo.author, exInfo.authorGitHub));
memcpy(exCollectionListUpdated + categoryIndex + textWritenSize, exCollectionList + categoryIndex, strlen(exCollectionList) - categoryIndex);
}
SaveFileText(exCollectionFilePath, exColInfoUpdated);
RL_FREE(exColInfoUpdated);
SaveFileText(exCollectionFilePath, exCollectionListUpdated);
RL_FREE(exCollectionListUpdated);
}
else LOG("WARNING: ADD: Example is already on the collection\n");
UnloadFileText(exColInfo);
UnloadFileText(exCollectionList);
//------------------------------------------------------------------------------------------------
// Update: Makefile, Makefile.Web, README.md, examples.js
@ -445,8 +509,24 @@ int main(int argc, char *argv[])
// Compile to: raylib.com/examples/<category>/<category>_example_name.wasm
// Compile to: raylib.com/examples/<category>/<category>_example_name.js
//------------------------------------------------------------------------------------------------
// TODO: Avoid platform-specific .BAT, not portable and it does not consider RESOURCES for Web properly,
// Makefile.Web should be used... but it requires proper editing first!
// TODO: Avoid platform-specific .BAT file
/*
SET RAYLIB_PATH=C:\GitHub\raylib
SET COMPILER_PATH=C:\raylib\w64devkit\bin
ENV_SET PATH=$(COMPILER_PATH)
SET MAKE=mingw32-make
$(MAKE) -f Makefile.Web shaders/shaders_deferred_render PLATFORM=$(PLATFORM) -B
//int putenv(char *string); // putenv takes a string of the form NAME=VALUE
//int setenv(const char *envname, const char *envval, int overwrite);
//int unsetenv(const char *name); //unset variable
putenv("RAYLIB_DIR=C:\\GitHub\\raylib");
putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
setenv("RAYLIB_DIR", "C:\\GitHub\\raylib", 1);
unsetenv("RAYLIB_DIR");
getenv("RAYLIB_DIR");
system(TextFormat("make -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exCategory, exName));
*/
system(TextFormat("%s/build_example_web.bat %s/%s", exBasePath, exCategory, exName));
// Copy results to web side
@ -461,7 +541,7 @@ int main(int argc, char *argv[])
//------------------------------------------------------------------------------------------------
} break;
case mi">3: // Rename
case nl">OP_RENAME: // Rename
{
// NOTE: At this point provided values have been validated:
// exName, exCategory, exRename, exRecategory
@ -536,27 +616,27 @@ int main(int argc, char *argv[])
TextFormat("%s/%s/%s.js", exWebPath, exRecategory, exRename));
} break;
case mi">4: // Remove
case nl">OP_REMOVE: // Remove
{
// Remove example from collection for files update
//------------------------------------------------------------------------------------------------
char *exColInfo = LoadFileText(exCollectionFilePath);
int exIndex = TextFindIndex(exColInfo, TextFormat("%s;%s", exCategory, exName));
char *exCollectionList = LoadFileText(exCollectionFilePath);
int exIndex = TextFindIndex(exCollectionList, TextFormat("%s;%s", exCategory, exName));
if (exIndex > 0) // Example found
{
char *exColInfoUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated list copy, 2MB
char *exCollectionListUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated list copy, 2MB
memcpy(exColInfoUpdated, exColInfo, exIndex);
memcpy(exCollectionListUpdated, exCollectionList, exIndex);
int lineLen = 0;
for (int i = exIndex; (exColInfo[i] != '\n') && (exColInfo[i] != '\0'); i++) lineLen++;
for (int i = exIndex; (exCollectionList[i] != '\n') && (exCollectionList[i] != '\0'); i++) lineLen++;
// Remove line and copy the rest next
memcpy(exColInfoUpdated + exIndex, exColInfo + exIndex + lineLen + 1, strlen(exColInfo) - exIndex - lineLen);
memcpy(exCollectionListUpdated + exIndex, exCollectionList + exIndex + lineLen + 1, strlen(exCollectionList) - exIndex - lineLen);
SaveFileText(exCollectionFilePath, exColInfoUpdated);
RL_FREE(exColInfoUpdated);
SaveFileText(exCollectionFilePath, exCollectionListUpdated);
RL_FREE(exCollectionListUpdated);
}
else LOG("WARNING: REMOVE: Example not found in the collection\n");
UnloadFileText(exColInfo);
UnloadFileText(exCollectionList);
//------------------------------------------------------------------------------------------------
// Remove: raylib/examples/<category>/resources/..
@ -620,7 +700,8 @@ int main(int argc, char *argv[])
remove(TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
} break;
case 5: // Validate
case OP_VALIDATE: // Validate: report and actions
case OP_UPDATE:
{
// TODO: Validate examples in collection list [examples_list.txt] -> Source of truth!
// Validate: raylib/examples/<category>/<category>_example_name.c -> File exists?
@ -707,7 +788,7 @@ static int UpdateRequiredFiles(void)
memcpy(mkTextUpdated, mkText, mkListStartIndex);
mkIndex = sprintf(mkTextUpdated + mkListStartIndex, "#EXAMPLES_LIST_START\n");
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{
mkIndex += sprintf(mkTextUpdated + mkListStartIndex + mkIndex, TextFormat("%s = \\\n", TextToUpper(exCategories[i])));
@ -743,7 +824,7 @@ static int UpdateRequiredFiles(void)
mkwIndex = sprintf(mkwTextUpdated + mkwListStartIndex, "#EXAMPLES_LIST_START\n");
// NOTE: We avoid the "others" category on web building
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES - 1; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++)
{
mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat("%s = \\\n", TextToUpper(exCategories[i])));
@ -769,7 +850,7 @@ static int UpdateRequiredFiles(void)
mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, "audio: $(AUDIO)\n\n");
// NOTE: We avoid the "others" category on web building
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES - 1; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++)
{
mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat("# Compile %s examples\n", TextToUpper(exCategories[i])));
@ -867,7 +948,7 @@ static int UpdateRequiredFiles(void)
mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, TextFormat("## EXAMPLES COLLECTION [TOTAL: %i]\n\n", exCollectionFullCount));
// NOTE: We keep a global examples counter
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{
int exCollectionCount = 0;
rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], false, &exCollectionCount);
@ -970,7 +1051,7 @@ static int UpdateRequiredFiles(void)
jsIndex += sprintf(jsTextUpdated + jsListStartIndex + jsIndex, " var exampleData = [\n");
// NOTE: We avoid "others" category
for (int i = 0; i < MAX_EXAMPLE_CATEGORIES - 1; i++)
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++)
{
int exCollectionCount = 0;
rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], false, &exCollectionCount);

Зареждане…
Отказ
Запис