Added feature page generation

Former-commit-id: 9d1b3db59f4d13ceb69212c289925c198eb14bc6
This commit is contained in:
Lynix 2015-03-18 17:11:24 +01:00
parent 5ab5e54242
commit 12c238ddae
5 changed files with 715 additions and 0 deletions

View File

@ -0,0 +1,239 @@
function PrintTable ( t, indent, done )
done = done or {}
indent = indent or 0
local txt = {}
for key, value in pairs (t) do
table.insert(txt, string.rep (" ", indent))
if (type(value) == "table" and not done[value]) then
done [value] = true
table.insert(txt, tostring(key) .. ":" .. "\n")
table.insert(txt, PrintTable (value, indent + 2, done))
else
table.insert(txt, tostring (key) .. "\t=\t" )
table.insert(txt, tostring(value) .. "\n" )
end
end
return table.concat(txt)
end
Feature = {}
-- Tables de vérité
local andTable =
{
{0,0},
{0,1},
}
local orTable =
{
{0,1},
{1,1},
}
local xorTable =
{
{0,1},
{1,0},
}
local bitFunc = function (a, b, truthTable)
local power = 1
local c = 0
while (a > 0 or b > 0) do
c = c + (truthTable[(a % 2)+1][(b % 2)+1] * power)
a = math.floor(a/2)
b = math.floor(b/2)
power = power * 2
end
return c
end
function Feature.AND(a, b)
return bitFunc(a, b, andTable)
end
function Feature.OR(a, b)
return bitFunc(a, b, orTable)
end
function Feature.XOR(a, b)
return bitFunc(a, b, xorTable)
end
Feature.NotApplicable = 0
Feature.Windows = 2 ^ 0
Feature.Linux = 2 ^ 1
Feature.MacOSX = 2 ^ 2
Feature.RaspberryPi = 2 ^ 3
Feature.POSIX = Feature.Linux + Feature.MacOSX + Feature.RaspberryPi
function Feature.CompleteData(tab, requiredPortability)
if (not requiredPortability) then
assert(tab.RequiredPortability)
requiredPortability = tab.RequiredPortability
elseif (tab.RequiredPortability) then
requiredPortability = Feature.OR(requiredPortability, tab.RequiredPortability)
end
tab.RequiredPortability = requiredPortability
if (not tab.Portability) then
tab.Portability = Feature.NotApplicable
end
if (tab.Features) then
local acc = 0
for k,v in pairs(tab.Features) do
if (type(v) == "string") then
v = {Title = v}
tab.Features[k] = v
end
Feature.CompleteData(v, requiredPortability)
v.Progress = v.Progress or 100
acc = acc + v.Progress
end
tab.Progress = acc/#tab.Features
end
end
function Feature.Generate()
local files = os.matchfiles("scripts/features/*.lua")
local modules = {}
for k, filePath in pairs(files) do
local moduleName = filePath:match(".*/(.*).lua")
local data = dofile(filePath)
Feature.CompleteData(data)
modules[moduleName] = data
end
local content = {}
local contentType =
{
["(%s*)%%MODULELIST%%"] = Feature.GenerateModuleList,
["(%s*)%%MODULEDESCRIPTION%%"] = Feature.GenerateModuleDescriptions,
["(%s*)%%DATE%%"] = function (dontcare, space, content)
table.insert(content, string.format("%s%s", space, os.date("%d/%m/%Y")))
end,
}
local index = io.open("scripts/features/index_template.html")
for line in index:lines() do
local matched = false
for k,v in pairs(contentType) do
local space = line:match(k)
if (space) then
matched = true
v(modules, space, content)
break
end
end
if (not matched) then
table.insert(content, line)
end
end
io.open("scripts/features/index.html", "w+"):write(table.concat(content, "\n"))
end
function Feature.Interpolate(from, to, p)
return from + (to - from)*p
end
function Feature.ComputeColor(progress)
local stable = {0, 200, 0}
local partial = {255, 127, 0}
local unusable = {255, 0, 0}
local a, b, p
if (progress < 20) then
a = unusable
b = partial
p = progress/20.0
else
a = partial
b = stable
p = math.min(20 * 1.020321705^(progress - 20), 100.0)/100.0 -- Je me complique certainement la vie pour ce qui est d'avoir une interpolation exponentielle, mais ça remonte tout ça ...
end
local color = {nil, nil, nil}
for i = 1, 3 do
color[i] = Feature.Interpolate(a[i], b[i], p)
end
return color
end
function Feature.GenerateModuleList(modules, space, content)
for k,v in pairs(modules) do
local c = Feature.ComputeColor(v.Progress)
table.insert(content, string.format([[%s<tr>]], space))
table.insert(content, string.format([[%s <td><a href="#%s">%s</a></td>]], space, k, v.Title))
table.insert(content, string.format([[%s <td style="color: rgb(%d, %d, %d);">%d%%</td>]], space, c[1], c[2], c[3], v.Progress))
table.insert(content, string.format([[%s</tr>]], space))
end
end
function Feature.GenerateModuleDescriptions(modules, space, content)
for k,v in pairs(modules) do
table.insert(content, string.format([[%s<div class="module">]], space))
table.insert(content, string.format([[%s <hr />]], space, k, v.Title))
table.insert(content, string.format([[%s <span id="%s" class="modulename">%s (%s) : %d%%</span>]], space, k, v.Title, v.LibName, math.floor(v.Progress)))
table.insert(content, string.format([[%s <h4>Fonctionnalités:</h4>]], space))
Feature.GenerateFeatureList(v.Features, space .. "\t\t", content)
table.insert(content, string.format([[%s</div>]], space))
end
end
function Feature.GenerateFeatureList(featureTable, space, content)
table.insert(content, string.format("%s<ul>", space))
for k,v in pairs(featureTable) do
local progress = v.Progress
local c = Feature.ComputeColor(progress)
local desc = (progress == 100) and "" or string.format(" (%d%%)", math.floor(progress))
table.insert(content, string.format("%s <li>", space))
table.insert(content, string.format([[%s <span style="color: rgb(%d, %d, %d);">%s%s</span>]], space, c[1], c[2], c[3], v.Title, desc))
if (v.Description) then
table.insert(content, string.format([[%s <br><span class="description">%s</span>]], space, v.Description))
end
if (v.Features) then
Feature.GenerateFeatureList(v.Features, space .. "\t\t\t", content)
end
if (v.Note) then
table.insert(content, string.format([[%s <br><span class="note">Note: <span class="notedesc">%s</span></span>]], space, v.Note))
end
if (v.Portability ~= Feature.NotApplicable and Feature.AND(v.Portability, v.RequiredPortability) ~= v.RequiredPortability) then
table.insert(content, string.format([[%s <br><span class="portability">Il manque une implémentation sur au moins un des OS supportés</span>]], space))
end
table.insert(content, string.format("%s </li>", space))
end
table.insert(content, string.format("%s</ul>", space))
end
newaction
{
trigger = "generatefeatures",
description = "Generate a web page describing each module's feature",
execute = Feature.Generate
}

View File

@ -0,0 +1,89 @@
return {
Title = "Module audio",
LibName = "NazaraAudio",
Description = "Module permettant de charger et jouer des sons, ainsi que d'accéder au microphone",
RequiredPortability = Feature.Windows + Feature.POSIX,
Features =
{
{
Title = "Gestion des émetteurs de sons (SoundEmitter)",
Description = "Classe de base dont héritent les sources sonores (Music, Sound)",
Features =
{
"Positionnement 3D (spatialisation) si désiré",
"Configuration de l'atténuation",
"Prise en charge de l'effet Doppler (vitesse du son)",
"Altération du ton (pitch)"
}
},
{
Title = "Gestion des tampons sonores (SoundBuffer)",
Description = "Tampon (buffer) stockant les échantillons (samples) décompressés, chargés à partir de fichiers sonores.",
Features =
{
{
Title = "Mixage mono",
Description = "Permet de mixer les différents canaux en un seul (mono), permettant la spatialisation.",
Note = "Le mixage mono n'est actuellement possible qu'au chargement du tampon depuis un fichier",
Progress = 90
}
}
},
{
Title = "Gestion des flux sonores (SoundStream)",
Description = "Interface permettant de définir un flux sonore de source indéfinie (fichier, réseau, etc.)"
},
{
Title = "Sons (Sound)",
Description = "Classe permettant de jouer un tampon sonore",
Features =
{
"Bouclage",
"Mise en pause",
"Récupération/positionnement de l'indice de lecture (offset)"
}
},
{
Title = "Sons streamés (Music)",
Description = "Classe permettant de jouer un son depuis un flux quelconque (SoundStream)",
Features =
{
"Streaming depuis un fichier sonore (+ mixage mono si demandé)",
"Bouclage",
"Mise en pause",
{Title = "Mixage mono", Note = "Le mixage mono devrait être possible au niveau du son lui-même plutôt qu'au niveau du loader", Progress = 0},
{Title = "Récupération/positionnement de l'indice de lecture (offset)", Progress = 0}
}
},
{
Title = "Configuration globale (Audio)",
Description = "Classe permettant de régler les différents paramètres généraux de l'environnement sonore",
Features =
{
"Positionnement/Orientation du listener",
"Réglage du volume général",
"Réglage de la vitesse du son/facteur Doppler"
}
},
{
Title = "Microphone",
Description = "Classe permettant l'accès aux microphones connectés à l'ordinateur",
Progress = 0
},
{
Title = "Environnement (EAX)",
Description = "Prise en charge de l'environnement",
Progress = 0
},
{
Title = "Formats supportés (chargement/streaming)",
Description = "Liste des formats de fichiers supportés par le loader inclus par le module (libsndfile)",
Note = "Le populaire format MP3 n'est pas supporté pour des raisons de royalties (mais la flexibilité du moteur vous permet de rajouter votre propre loader MP3)",
Features =
{
"aiff", "au", "avr", "caf", "flac", "htk", "ircam", "mat4", "mat5", "mpc2k", "nist","ogg", "pvf", "raw", "rf64", "sd2", "sds", "svx", "voc", "w64", "wav", "wve"
}
}
}
}

View File

@ -0,0 +1,204 @@
return {
Title = "Noyau",
LibName = "NazaraCore",
Description = "Noyau du moteur, possède les fonctionnalités utilisées partout ailleurs dans le moteur.",
RequiredPortability = Feature.Windows + Feature.POSIX,
Features =
{
{
Title = "Classes utilitaires de base",
Description = "Classes assurant certaines fonctionnalités de base destinées à aider le programmeur.",
Features =
{
{
Title = "Chaînes de caractère unicode (String)",
Description = "Classe supplantant std::string, rajoutant le support de l'UTF-8 et quelques opérations utiles (rechercher/remplacer, correspondance par motif, ..)."
},
{
Title = "Exécution de code lors de la destruction (CallOnExit)",
Description = "Permet l'appel d'une fonction/lambda à la destruction de cet objet, en accordance avec le RAII/RRID."
},
{
Title = "Gestion de l'initialisation/libération statique de classes, en accordance avec le RAII/RRID",
Description = "Permet d'initialiser et de libérer automatiquement des classes possédant des fonctions membres statiques Initialize/Uninitialize, selon un ordre de dépendance, comme par exemple les classes des modules du moteur lui-même."
},
{
Title = "Gestion des couleurs (Color)",
Description = "Classe permettant de stocker et effectuer des opérations sur des couleurs (conversion, mélange, etc.)."
},
{
Title = "Gestion de primitives, au sens géométrique (Primitive, PrimitiveList)",
Description = "Structures définissant certaines primitives géométriques (boite, cône, plan, sphère), utiles pour la génération de meshs (de rendu ou physiques)."
},
{
Title = "OffsetOf",
Description = "Fonction permettant de récupérer à la compilation l'adresse locale (déclage d'octets) d'un membre de n'importe quelle structure/classe."
},
{
Title = "Pointeurs à écart (stride) indépendant (SparsePtr)",
Description = "Classe se comportant comme un pointeur, à l'exception de l'écart entre deux éléments (opérations d'accès, d'addition et de soustraction) qui est indépendant du type pointé."
},
{
Title = "Stockage et gestion de champs de bits dynamiques (Bitset)",
Description = "Classe permettant le stockage et la manipulation optimisée d'un nombre élevé et dynamique de bits (=booléens, opérations de comptage, recherche de bits activés, opérations entre champs de bits, etc.)",
Note = "Il manque des opérateurs de comparaison et une spécialisation de la fonction de hachage",
Progress = 90
}
}
},
{
Title = "Gestion de fichiers et dossiers (File/Directory)",
Description = "Classes supportant les chemins unicodes et les tailles 64 bits, ainsi que quelques opérations sur les chemins (normalisation, transformation d'un chemin relatif en chemin absolu).",
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "Gestion de l'endianness",
Description = "Boutisme, récupération à la compilation ou à l'exécution, possibilité de lire des fichiers en corrigeant le boutisme des objets lors de la lecture."
},
{
Title = "Gestion de bibliothèques dynamiques (DynLib)",
Description = "Classe permettant de charger à l'exécution des bibliothèques dynamiques (selon la plateforme: .dll/.so/.dynlib) et d'en extraire des fonctions.",
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "Fonctions de hachage",
Description = "Possibilité de hacher (calculer une somme de contrôle) de n'importe quelles données, chaîne de caractère ou fichier.",
Features =
{
{Title = "CRC16", Progress = 0},
"CRC32",
"Fletcher16",
{Title = "Fletcher32", Progress = 0},
"MD5",
"SHA-1",
"SHA-224",
"SHA-256",
"SHA-384",
"SHA-512",
"Whirlpool"
}
},
{
Title = "Gestion de la mémoire",
Description = "Set de fonctionnalités permettant d'aider le programmeur à gérer la mémoire de son programme.",
Features =
{
{
Title = "MemoryManager",
Description = "Classe permettant de suivre les allocations de mémoire et éventuels leaks, peut suivre automatiquement chaque allocation du programme."
},
{
Title = "MemoryPool",
Description = "Classe permettant d'allouer/libérer des blocs de mémoire de taille prédéfinie à coût constant."
}
}
},
{
Title = "Gestion de l'exécution concurrentielle",
Description = "Set de fonctionnalités liées à l'exécution et la synchronisation entre processus légers (threads) sans dépendance sur la bibliothèque standard.",
Features =
{
{
Title = "Thread",
Description = "Classe permettant d'appeler une fonction (avec passage d'arguments) dans un thread, supporte une interface similaire à std::thread.",
Note = "Il n'est pas encore possible de récupérer le Thread::Id courant",
Progress = 95,
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "Mutex",
Description = "Primitive de synchronisation binaire (exclusion mutuelle).",
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "Semaphore",
Description = "Primitive de synchronisation à N concurrents simultanés.",
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "ConditionVariable",
Description = "Primitive de synchronisation à signaux.",
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "LockGuard",
Description = "Classe utilitaire permettant de verrouiller/déverrouiller une mutex en accordance avec le RAII/RRID."
},
{
Title = "TaskScheduler",
Description = "Classe permettant de répartir X tâches sur Y workers de façon efficace.",
Portability = Feature.Windows
}
}
},
{
Title = "Gestion du temps",
Description = "Classes/fonctions permettant de gérer le temps dans un programme.",
Features =
{
{
Title = "Récupération du temps en millisecondes ou en microsecondes",
Description = "Permet de récupérer le nombre de millisecondes ou de microsecondes (si supporté par le système) écoulées depuis un référentiel constant (référentiel indéterminé).",
Portability = Feature.Windows + Feature.POSIX
},
{
Title = "Clock",
Description = "Classe chronomètre permettant de mesurer le temps écoulé depuis un évènement précis, supporte la mise en pause."
}
}
},
{
Title = "Gestion de compteurs de référence",
Description = "Set de classes permettant de gérer des pointeurs intelligents partagés intrusifs.",
},
{
Title = "Gestion de liste de paramètres",
Description = "Classe gérant une liste de paramètres nommées à type variable.",
},
{
Title = "Gestion de ressources (chargement/gestion)",
Description = "Set de classes s'occupant du chargement et de la gestion de certaines classes spéciales, appartenant au groupe des ressources (ex: chargée depuis un fichier).",
Features =
{
{
Title = "ResourceLibrary",
Description = "Classe template chargée du stockage de ressources de façon nommée."
},
{
Title = "ResourceLoader",
Description = "Classe template chargée de stocker et gérer des loaders (fonctions s'occupant de transformer un flux de données en ressource)."
},
{
Title = "ResourceManager",
Description = "Classe template chargée de charger et mettre en cache des ressources depuis un chemin de fichier."
}
}
},
{
Title = "Gestion des plugins",
Description = "Capacité d'extension du moteur à l'aide de bibliothèques dynamiques conçues dans cette optique.",
Note = "Nécessite une révision, permettant aux plugins de se signaler (nom, version)",
Progress = 80
},
{
Title = "Gestion de l'empaquetage bidimensionnel",
Description = "Algorithmes permettant de placer des rectangles 2D arbitraires dans un espace prédéfini de façon à minimiser la perte d'espace.",
Note = "Algorithme Guillotine terminé, algorithme Skyline manquant",
Progress = 60
},
{
Title = "Gestion de l'Unicode",
Description = "Récupération d'informations sur les caractères Unicode (si les données Unicode sont incorporées au programme).",
Note = "Il manque l'intégration des UnicodeData dans le moteur",
Progress = 20
},
{
Title = "Récupération d'informations sur le hardware",
Description = "Classe permettant, si la plateforme le supporte, de récupérer des informations utiles sur le matériel: nom et fabricant du processeur, nombre de coeurs, support d'un set d'extension (exemple: SSE), quantité de mémoire vive, exécution de l'instruction CPUID.",
Note = "Il manque de quoi récupérer la quantité de mémoire vive",
Progress = 90,
Portability = Feature.Windows + Feature.POSIX
}
}
}

View File

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
<title>Avancement de Nazara</title>
</head>
<body>
<p class="centre">
<img src="https://github.com/DigitalPulseSoftware/NazaraEngine/raw/master/Logo.png" alt="Nazara Engine" />
<br>
<br>
Retrouvez le moteur sur GitHub !
<br>
<a href="https://github.com/DigitalPulseSoftware/NazaraEngine">Dépôt Github</a><br><br>
Ou venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs site webs:
<br>
<a href="http://openclassrooms.com/forum/sujet/moteur-de-jeu-nazara-engine-69732">OpenClassrooms</a> ou <a href="http://pdp.microjoe.org/forums/sujet/354/projet-nazara-engine-moteur-de-jeu">Progdupeupl</a> ou <a href="http://zestedesavoir.com/forums/sujet/1039/nazara-engine">ZesteDeSavoir</a>
<br>
<br>
... ou pourquoi ne pas venir faire un tour sur <a href="http://forum.digitalpulsesoftware.com">le forum dédié au moteur</a> ?
</p>
<div class="centre">
<h1>Fonctionnalités de Nazara</h1>
<br>
Dernière mise à jour:
<span class="lastupdate">
%DATE%
</span>
<br>
<br>
<h2>Important:</h2><br>
Afin de faciliter la mise à jour, la page que vous voyez ici a été généré automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps.<br>
C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.<br>
Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.<br>
<br>
Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai <u>essayé</u> de minimiser les dégats).<br>
Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide sera grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).
<br>
<br>
Le pourcentage indiqué est calculé automatiquement en fonction des <u>fonctionnalités</u>,<br>cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle,<br><u>cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité</u> (cependant cela signifie que la fonctionnalité est utilisable).<br>
Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.
<br>
<br>
<table>
<caption>Sommaire</caption>
<thead>
<tr>
<th>Module</th>
<th>Avancement</th>
</tr>
</thead>
<tbody>
%MODULELIST%
</tbody>
</table>
</div>
%MODULEDESCRIPTION%
<hr />
<div class="centre">
<table>
<caption>Sommaire</caption>
<thead>
<tr>
<th>Module</th>
<th>Pourcentage</th>
</tr>
</thead>
<tbody>
%MODULELIST%
</tbody>
</table>
</div>
</body>
</html>

View File

@ -0,0 +1,108 @@
/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */
body
{
background-color: black;
color: white;
}
a
{
color: #007ACC;
}
a:hover
{
color: lightblue;
}
h1
{
display: inline;
}
h2
{
display: inline;
text-decoration: underline;
}
h4
{
text-decoration: underline;
}
ol
{
list-style-type: none;
}
table
{
border-collapse: collapse;
text-align: center;
display: inline-block;
border: white groove;
border-radius: 10px;
box-shadow: 0px 0px 10px lightblue;
}
th
{
text-shadow: 2px 2px 4px black;
}
tr
{
border: 1px solid white;
}
tbody tr:hover
{
text-shadow: 0px 0px 4px white;
}
.centre
{
text-align: center;
}
.description
{
margin-left: 20px;
}
.lastupdate
{
font-size: x-large;
font-weight: bold;
color: yellow;
}
.module
{
}
.modulename
{
font-size: x-large;
font-weight: bold;
text-shadow: 2px 2px 10px white;
}
.note
{
margin-left: 20px;
color: #007ACC;
}
.notedesc
{
color: rgb(200, 200, 255);
}
.portability
{
margin-left: 20px;
color: red;
}