mirror of https://github.com/marrub--/zscript-doc
Compare commits
3 Commits
c7a56af98e
...
9025bda4ad
Author | SHA1 | Date |
---|---|---|
an | 9025bda4ad | |
an | 7e071b7622 | |
an | cd38527f4d |
|
@ -12,8 +12,10 @@ The user-defined stat numbers begin at `Thinker.STAT_USER` and end at
|
||||||
`Thinker.STAT_USER_MAX`. Do not attempt to use normal integers as stat numbers
|
`Thinker.STAT_USER_MAX`. Do not attempt to use normal integers as stat numbers
|
||||||
except as relative to these two.
|
except as relative to these two.
|
||||||
|
|
||||||
(Note to authors: These tables are not alphabetically organized as their
|
<!--
|
||||||
ordering is meaningful.)
|
NOTE: These tables are not alphabetically organized as their ordering is
|
||||||
|
meaningful.
|
||||||
|
-->
|
||||||
|
|
||||||
Thinkers which do not think and are elided from many checks:
|
Thinkers which do not think and are elided from many checks:
|
||||||
|
|
||||||
|
|
10
api.md
10
api.md
|
@ -22,12 +22,6 @@ sense to user code, but are fine to the engine. Because of this, the API shall
|
||||||
be documented in pseudo-ZScript which gives an idea of how it works for the
|
be documented in pseudo-ZScript which gives an idea of how it works for the
|
||||||
modder rather than for the engine.
|
modder rather than for the engine.
|
||||||
|
|
||||||
Note to authors: Capitalization is normalized within this documentation to
|
|
||||||
encourage consistent code, and does not follow ZScript's original
|
|
||||||
capitalization exactly. Similarly, argument names in methods are sometimes
|
|
||||||
renamed. Note well that *arguments with defaults MAY NOT be renamed* as they
|
|
||||||
are part of the API.
|
|
||||||
|
|
||||||
# Actors
|
# Actors
|
||||||
|
|
||||||
<!-- inter-toc actor -->
|
<!-- inter-toc actor -->
|
||||||
|
@ -113,7 +107,9 @@ For legacy reasons, many intermission-related things may be prefixed with `WI`
|
||||||
or `WB`. The abbreviation `WI` means *World Intermission* (the intermission
|
or `WB`. The abbreviation `WI` means *World Intermission* (the intermission
|
||||||
screen was originally called "World Map" by Tom Hall) and `WB` meaning *World
|
screen was originally called "World Map" by Tom Hall) and `WB` meaning *World
|
||||||
Buffer*, as this data was originally buffered into a specific memory address
|
Buffer*, as this data was originally buffered into a specific memory address
|
||||||
for [statistics drivers](https://doomwiki.org/wiki/Statistics_driver).
|
for [statistics drivers][1].
|
||||||
|
|
||||||
|
[1]: https://doomwiki.org/wiki/Statistics_driver
|
||||||
|
|
||||||
# Level Data
|
# Level Data
|
||||||
|
|
||||||
|
|
71
entry.md
71
entry.md
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
* [ACS](#acs)
|
* [ACS](#acs)
|
||||||
* [Actors](#actors)
|
* [Actors](#actors)
|
||||||
|
* [Examples: Actor Replacement](#examples-actor-replacement)
|
||||||
* [Console Commands](#console-commands)
|
* [Console Commands](#console-commands)
|
||||||
* [CVARINFO](#cvarinfo)
|
* [CVARINFO](#cvarinfo)
|
||||||
* [DECALDEF](#decaldef)
|
* [DECALDEF](#decaldef)
|
||||||
|
@ -22,7 +23,7 @@ itself, many interactions with the engine are not defined in ZScript. This
|
||||||
section describes all ZScript interactions with the engine, both inside and
|
section describes all ZScript interactions with the engine, both inside and
|
||||||
outside of ZScript itself.
|
outside of ZScript itself.
|
||||||
|
|
||||||
# ACS
|
## ACS
|
||||||
|
|
||||||
ACS has several functions for interfacing with ZScript: `SetUserVariable`
|
ACS has several functions for interfacing with ZScript: `SetUserVariable`
|
||||||
(callfunc `24`,) `GetUserVariable` (callfunc `25`,) `SetUserArray` (callfunc
|
(callfunc `24`,) `GetUserVariable` (callfunc `25`,) `SetUserArray` (callfunc
|
||||||
|
@ -55,7 +56,7 @@ values, although more than one value will be ignored. The returned value may be
|
||||||
`double` (converted to fixed-point,) `name`, `sound` or `string` (converted to
|
`double` (converted to fixed-point,) `name`, `sound` or `string` (converted to
|
||||||
ACS string.) If it is not one of these types, it will be ignored.
|
ACS string.) If it is not one of these types, it will be ignored.
|
||||||
|
|
||||||
# Actors
|
## Actors
|
||||||
|
|
||||||
Actor classes can be replaced by the `replaces` class flag, which during
|
Actor classes can be replaced by the `replaces` class flag, which during
|
||||||
dynamic actor replacement will choose to spawn this class over its replaced
|
dynamic actor replacement will choose to spawn this class over its replaced
|
||||||
|
@ -63,72 +64,94 @@ actor, unless the replaced actor is later replaced again by another class.
|
||||||
Dynamic actor replacement can also be overridden with an event handler's
|
Dynamic actor replacement can also be overridden with an event handler's
|
||||||
`CheckReplacement` virtual function.
|
`CheckReplacement` virtual function.
|
||||||
|
|
||||||
For example:
|
### Examples: Actor Replacement
|
||||||
|
|
||||||
```
|
```
|
||||||
class MyActor : Actor replaces OtherActor {} // OtherActor will be dynamically replaced with MyActor
|
// Some actor.
|
||||||
class MyOtherActor : Actor replaces OtherActor {} // OtherActor will now be replaced with MyOtherActor instead of MyActor
|
class OtherActor : Actor
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// OtherActor will be dynamically replaced with MyActor.
|
||||||
|
class MyActor : Actor replaces OtherActor
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// OtherActor will now be replaced with MyOtherActor instead of MyActor.
|
||||||
|
class MyOtherActor : Actor replaces OtherActor
|
||||||
|
{
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Console Commands
|
## Console Commands
|
||||||
|
|
||||||
While ZScript cannot be directly called by console commands, one can use the
|
While ZScript cannot be directly called by console commands, one can use the
|
||||||
`event` and `netevent` console commands. `event` will dispatch a non-player
|
`event` and `netevent` console commands. `event` will dispatch a non-player
|
||||||
network event, and `netevent` will dispatch a network event for the player that
|
network event, and `netevent` will dispatch a network event for the player that
|
||||||
ran it.
|
ran it.
|
||||||
|
|
||||||
# CVARINFO
|
## CVARINFO
|
||||||
|
|
||||||
Any CVars declared as a server CVar in `CVARINFO` or by the engine will be
|
Any CVars declared as a server CVar in `CVARINFO` or by the engine will be
|
||||||
accessible as a global variable in ZScript, which has a special type that can
|
accessible as a global variable in ZScript, which has a special type that can
|
||||||
be implicitly cast to the type of the CVar. They cannot be set this way, only
|
be implicitly cast to the type of the CVar. They cannot be set this way, only
|
||||||
accessed.
|
accessed.
|
||||||
|
|
||||||
# DECALDEF
|
## DECALDEF
|
||||||
|
|
||||||
`DECALDEF` can set the decal generator for a specific `Actor` class with the
|
`DECALDEF` can set the decal generator for a specific `Actor` class with the
|
||||||
`generator` keyword. An actor can also define its generator and inherited
|
`generator` keyword. An actor can also define its generator and inherited
|
||||||
classes' generators with the `Decal` property.
|
classes' generators with the `Decal` property.
|
||||||
|
|
||||||
# DECORATE
|
## DECORATE
|
||||||
|
|
||||||
TODO: lots of things to note here
|
TODO: lots of things to note here
|
||||||
|
|
||||||
# LOCKDEFS
|
## LOCKDEFS
|
||||||
|
|
||||||
Key and lock groups in `LOCKDEFS` are defined as groups of `Inventory` or `Key`
|
Key and lock groups in `LOCKDEFS` are defined as groups of `Inventory` or `Key`
|
||||||
descendants.
|
descendants.
|
||||||
|
|
||||||
# GLDEFS
|
## GLDEFS
|
||||||
|
|
||||||
Lights can be associated with `Actor` classes and frames in `GLDEFS`.
|
Lights can be associated with `Actor` classes and frames in `GLDEFS`.
|
||||||
|
|
||||||
# KEYCONF
|
## KEYCONF
|
||||||
|
|
||||||
TODO: this can be used for custom buttons
|
TODO: this can be used for custom buttons
|
||||||
|
|
||||||
# MAPINFO
|
## MAPINFO
|
||||||
|
|
||||||
In `MAPINFO`, the `GameInfo` block (referred to as `MAPINFO`/GameInfo in this
|
In `MAPINFO`, the `GameInfo` block (referred to as `MAPINFO`/GameInfo in this
|
||||||
document) the following properties interact directly with ZScript:
|
document) the following properties interact directly with ZScript:
|
||||||
|
|
||||||
- `EventHandlers` and `AddEventHandlers` override or add to the list of `StaticEventHandler` or `EventHandler` classes registered by the game (as opposed to event handlers registered per-map.)
|
- `EventHandlers` and `AddEventHandlers` override or add to the list of
|
||||||
- `MessageBoxClass` sets the `MessageBoxMenu` class to use for message boxes used by the engine's GUI.
|
`StaticEventHandler` or `EventHandler` classes registered by the game (as
|
||||||
- `PlayerClasses` and `AddPlayerClasses` override or add to the list of `PlayerPawn` classes the game provides.
|
opposed to event handlers registered per-map.)
|
||||||
- `PrecacheClasses` will pre-cache all sprites used by an `Actor` class. Note that this also works for `StateProvider` degenerates like `Weapon`.
|
- `MessageBoxClass` sets the `MessageBoxMenu` class to use for message boxes
|
||||||
- `StatScreen_CoOp` sets the `StatusScreen` class to use for co-op intermission screens.
|
used by the engine's GUI.
|
||||||
- `StatScreen_DM` sets the `StatusScreen` class to use for Deathmatch intermission screens.
|
- `PlayerClasses` and `AddPlayerClasses` override or add to the list of
|
||||||
- `StatScreen_Single` sets the `StatusScreen` class to use for single-player intermission screens.
|
`PlayerPawn` classes the game provides.
|
||||||
- `StatusBarClass` sets the status bar class used by the game to the provided `BaseStatusBar` class.
|
- `PrecacheClasses` will pre-cache all sprites used by an `Actor` class. Note
|
||||||
- `WeaponSlot` sets the game's default weapon slots to the provided `Weapon` classes.
|
that this also works for `StateProvider` degenerates like `Weapon`.
|
||||||
|
- `StatScreen_CoOp` sets the `StatusScreen` class to use for co-op intermission
|
||||||
|
screens.
|
||||||
|
- `StatScreen_DM` sets the `StatusScreen` class to use for Deathmatch
|
||||||
|
intermission screens.
|
||||||
|
- `StatScreen_Single` sets the `StatusScreen` class to use for single-player
|
||||||
|
intermission screens.
|
||||||
|
- `StatusBarClass` sets the status bar class used by the game to the provided
|
||||||
|
`BaseStatusBar` class.
|
||||||
|
- `WeaponSlot` sets the game's default weapon slots to the provided `Weapon`
|
||||||
|
classes.
|
||||||
|
|
||||||
TODO: there are other things here as well, like map event handlers
|
TODO: there are other things here as well, like map event handlers
|
||||||
|
|
||||||
# MENUDEF
|
## MENUDEF
|
||||||
|
|
||||||
TODO: this directly uses ZScript classes
|
TODO: this directly uses ZScript classes
|
||||||
|
|
||||||
# TERRAIN
|
## TERRAIN
|
||||||
|
|
||||||
The `SmallSplash`, `SplashBase` and `SplashChunk` properties of `Splash` blocks
|
The `SmallSplash`, `SplashBase` and `SplashChunk` properties of `Splash` blocks
|
||||||
use `Actor`s.
|
use `Actor`s.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# Concepts
|
# Concepts
|
||||||
|
|
||||||
|
<!-- vim-markdown-toc GFM -->
|
||||||
|
|
||||||
* [Action Scoping](#action-scoping)
|
* [Action Scoping](#action-scoping)
|
||||||
* [Object Scoping](#object-scoping)
|
* [Object Scoping](#object-scoping)
|
||||||
* [Format String](#format-string)
|
* [Format String](#format-string)
|
||||||
|
@ -7,7 +9,13 @@
|
||||||
* [Game Tick](#game-tick)
|
* [Game Tick](#game-tick)
|
||||||
* [Interpolation](#interpolation)
|
* [Interpolation](#interpolation)
|
||||||
|
|
||||||
TODO
|
<!-- vim-markdown-toc -->
|
||||||
|
|
||||||
|
Here is a cursory view of concepts vital to ZScript and ZDoom in general. If
|
||||||
|
you can't find something here, it's likely inherited directly from Doom, so you
|
||||||
|
should check [the Doom Wiki][1] for more relevant information.
|
||||||
|
|
||||||
|
[1]: https://doomwiki.org/wiki/Entryway
|
||||||
|
|
||||||
## Action Scoping
|
## Action Scoping
|
||||||
|
|
||||||
|
@ -61,15 +69,18 @@ Here is a chart of data access possibilities for each scope:
|
||||||
|
|
||||||
A format string is a string that specifies the format of a conversion from
|
A format string is a string that specifies the format of a conversion from
|
||||||
arbitrary data to a contiguous character string. A format string contains
|
arbitrary data to a contiguous character string. A format string contains
|
||||||
normal characters and *conversion specifiers*. See [this
|
normal characters and *conversion specifiers*. See [this page][2] for more
|
||||||
page](https://en.cppreference.com/w/c/io/fprintf) for more information.
|
information. Differences between C's `printf` and ZScript formats include:
|
||||||
Differences between C's `printf` and ZScript formats include:
|
|
||||||
|
|
||||||
- Since there's no `char` type, `int` is used for `%c`.
|
- Since there's no `char` type, `int` is used for `%c`.
|
||||||
- `%s` also works for `name`.
|
- `%s` also works for `name`.
|
||||||
- No `%n` specifier.
|
- No `%n` specifier.
|
||||||
- An additional conversion specifier `%B` exists which converts a number to binary.
|
- An additional conversion specifier `%B` exists which converts a number to
|
||||||
- An additional conversion specifier `%H` exists which works like `%g` but automatically selects the smallest appropriate precision.
|
binary.
|
||||||
|
- An additional conversion specifier `%H` exists which works like `%g` but
|
||||||
|
automatically selects the smallest appropriate precision.
|
||||||
|
|
||||||
|
[2]: https://en.cppreference.com/w/c/io/fprintf
|
||||||
|
|
||||||
## Sprite
|
## Sprite
|
||||||
|
|
||||||
|
@ -81,7 +92,9 @@ the file and state block representations, not a character, but an integer. The
|
||||||
number `0` for instance represents the letter `A`, `1` to `B`, etc.
|
number `0` for instance represents the letter `A`, `1` to `B`, etc.
|
||||||
|
|
||||||
For more information on sprites and rotations, please refer to [the relevant
|
For more information on sprites and rotations, please refer to [the relevant
|
||||||
Doom Wiki article](https://doomwiki.org/wiki/Sprite).
|
Doom Wiki article][3].
|
||||||
|
|
||||||
|
[3]: https://doomwiki.org/wiki/Sprite
|
||||||
|
|
||||||
## Game Tick
|
## Game Tick
|
||||||
|
|
||||||
|
@ -108,7 +121,9 @@ simulation in the same way:
|
||||||
smoother rendering.
|
smoother rendering.
|
||||||
|
|
||||||
For more information on ticks, please refer to [the relevant Doom Wiki
|
For more information on ticks, please refer to [the relevant Doom Wiki
|
||||||
article](https://doomwiki.org/wiki/Tic).
|
article][4].
|
||||||
|
|
||||||
|
[4]: https://doomwiki.org/wiki/Tic
|
||||||
|
|
||||||
## Interpolation
|
## Interpolation
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
# Style
|
||||||
|
|
||||||
|
<!-- vim-markdown-toc GFM -->
|
||||||
|
|
||||||
|
* [Capitalization Conventions](#capitalization-conventions)
|
||||||
|
* [Rationale](#rationale)
|
||||||
|
* [Word Choice](#word-choice)
|
||||||
|
* [Rationale](#rationale-1)
|
||||||
|
* [Naming Type Members](#naming-type-members)
|
||||||
|
* [Rationale](#rationale-2)
|
||||||
|
* [Layout Conventions](#layout-conventions)
|
||||||
|
* [Rationale](#rationale-3)
|
||||||
|
* [Commenting Conventions](#commenting-conventions)
|
||||||
|
* [Rationale](#rationale-4)
|
||||||
|
* [Language Guidelines](#language-guidelines)
|
||||||
|
* [Rationale](#rationale-5)
|
||||||
|
|
||||||
|
<!-- vim-markdown-toc -->
|
||||||
|
|
||||||
|
This is a style guide for the ZScript documentation to encourage best-practice
|
||||||
|
coding with it, focused on clarity and consistency of formatting. It is also
|
||||||
|
intended to be a general style guide for writing new code, but this purpose is
|
||||||
|
ancillary and can be ignored. Within the abstract of each component of style
|
||||||
|
will be rationale for choices made.
|
||||||
|
|
||||||
|
## Capitalization Conventions
|
||||||
|
|
||||||
|
ZScript is case insensitive, however this guide aims to give a way to
|
||||||
|
consistently capitalize all identifiers in the language. Due to case
|
||||||
|
insensitivity, it may be difficult to apply these guidelines to real code, but
|
||||||
|
nonetheless a consistent capitalization style should be followed. Do note that
|
||||||
|
you must not rely on case differences in identifiers due to this.
|
||||||
|
|
||||||
|
Capitalize the first letter of each word in an identifier. Acronyms over 2
|
||||||
|
characters in length are considered whole words, so for instance prefer
|
||||||
|
`XmlWidget` over `XMLWidget` but `IOStream` over `IoStream`. Acronyms of one
|
||||||
|
character also count, so prefer `PrintF` over `Printf`.
|
||||||
|
|
||||||
|
For identifiers of parameter names and local scope variables do not capitalize
|
||||||
|
the first word. In these cases, prefer `xmlWidget` over `XmlWidget` or
|
||||||
|
`ioStream` over `IOStream`. The same for acronyms of one character, so `typeF`
|
||||||
|
over `TypeF` or `nChars` over `NChars`. (Note that the former two are malformed
|
||||||
|
names, however. See the "Word Choice" section for more information.)
|
||||||
|
|
||||||
|
Identifiers used for flags (declared with `flagdef`) and constants (declared
|
||||||
|
with `const`, `static const`, or `enum`) must be all uppercase, except the `b`
|
||||||
|
prefix on flags, and can separate words with underscores.
|
||||||
|
|
||||||
|
Argument names in base archive methods may be renamed, but arguments with
|
||||||
|
defaults may not be renamed as they are part of the API.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Case insensitivity in programming is generally regarded as bad practice because
|
||||||
|
the lack of strictness is often a failing in language design. It is not
|
||||||
|
imperative here to reason for or against case insensitivity, however. Code
|
||||||
|
within this style is to be written as uniformly as possible, therefore
|
||||||
|
capitalization is also to be uniform. It is the user's choice whether to follow
|
||||||
|
this rule or not, just as any other, but for authors of this documentation the
|
||||||
|
sole imperative is consistency.
|
||||||
|
|
||||||
|
This style of acronym capitalization has been chosen so as to defer to prior
|
||||||
|
art, primarily C#'s standard, which has been in use for over a decade now. The
|
||||||
|
purpose of not capitalizing more than two characters is to make it more natural
|
||||||
|
to read acronyms where normally they are forced to be next to other capitalized
|
||||||
|
words.
|
||||||
|
|
||||||
|
Not capitalizing the first word of parameter and local scope variables is also
|
||||||
|
decided by deferring to prior art. The majority of programming style guides
|
||||||
|
written advocate for this. The purpose in ZScript is primarily moot due to case
|
||||||
|
insensitivity, but we apply these rules to make reading easier and more
|
||||||
|
consistent with most other programming languages that have existed.
|
||||||
|
|
||||||
|
Capitalizing constants, enumerations, and flags is an artifact of the way they
|
||||||
|
are declared in ZDoom, and also in the original Linux Doom source code. This is
|
||||||
|
extended to static arrays for consistency.
|
||||||
|
|
||||||
|
## Word Choice
|
||||||
|
|
||||||
|
In new identifiers, do not add underscores anywhere within the identifier,
|
||||||
|
unless explicitly stated in this style guide or necessary because of
|
||||||
|
unmodifiable code (such as that in GZDoom's base archive.) Do not use Hungarian
|
||||||
|
notation.
|
||||||
|
|
||||||
|
Do not use keywords or types as names except for the identifier "`name`". Do
|
||||||
|
not, for instance, declare `string Class;`, even though the language will allow
|
||||||
|
you to do so, although `string Name;` is fine.
|
||||||
|
|
||||||
|
It is generally favorable to use shortened terminology, for instance `CanMoveZ`
|
||||||
|
instead of `CanMoveVertically`. Try to make names readable in English, however:
|
||||||
|
`CanThrowItem` instead of `ThrowableItem`.
|
||||||
|
|
||||||
|
In the same vein, use abbreviations where conventional, but avoid them where
|
||||||
|
unnecessary. Prefer `GetMobj` to `GetMapObject` but also `GetAngle` to
|
||||||
|
`GetAng`.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The forbidding of underscores and Hungarian notation are in accordance with
|
||||||
|
ZDoom's coding style. These choices are also present in other prior art, but
|
||||||
|
the main deciding factor is that of the engine itself.
|
||||||
|
|
||||||
|
The usage of most keywords in variable names is allowed in ZScript because the
|
||||||
|
parser considers most identifiers to be contextual. In many contexts, keywords
|
||||||
|
are allowed in places they shouldn't be by most standards. Besides the
|
||||||
|
precedence of prior art, it appears that the engine itself also avoids
|
||||||
|
(ab)using this relaxation of context.
|
||||||
|
|
||||||
|
The engine and this style do, however, allow use of the identifier "`name`" in
|
||||||
|
variables and members because it is a frequently used word and would be absurd
|
||||||
|
to disallow.
|
||||||
|
|
||||||
|
Shortened terminology such as abbreviations or contractions are favored due to
|
||||||
|
long-standing conventions within ZDoom's source code. This is also historically
|
||||||
|
relevant because of engines such as Unreal Engine which ZDoom takes inspiration
|
||||||
|
from. Common terminology which may be shortened can be found on [the Doom
|
||||||
|
Wiki.][2]
|
||||||
|
|
||||||
|
[2]: https://doomwiki.org/wiki/Category:Doom_engine
|
||||||
|
|
||||||
|
## Naming Type Members
|
||||||
|
|
||||||
|
Always name methods with verbs or verb phrases, such as "`Split`" or
|
||||||
|
"`CompareTo`." Always try to make names forward compatible, i.e. such that they
|
||||||
|
will likely not conflict with new functions when they are added to the engine.
|
||||||
|
In mods, this can even involve prefixing method names with one unique to the
|
||||||
|
mod. Avoid violent words such as `Die`, `Destroy`, `Kill`, except where
|
||||||
|
literally applicable. Prefer for instance `Stop`, `Drop`, `Halt`.
|
||||||
|
|
||||||
|
Always name members with nouns, noun phrases or adjectives. Boolean values
|
||||||
|
should often be prefixed with `Is`, `Has`, and other existential present-tense
|
||||||
|
verbs. All members of class types should be prefixed with `m_`, despite rules
|
||||||
|
against Hungarian notation and underscores. Try to name members productively
|
||||||
|
rather than vaguely, instead of `RefInt` write `RefCount`.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Forwards compatibility is necessary primarily in mods. In this documentation it
|
||||||
|
should be taken into account when writing example code, often when writing
|
||||||
|
examples that involve inheriting from a class in the engine. ZScript will hard
|
||||||
|
error on load if there is more than one definition of a function, so it is
|
||||||
|
necessary to never have a conflict in names, including capitalization-wise.
|
||||||
|
|
||||||
|
The purpose of avoiding violent words in method names is to not unnecessarily
|
||||||
|
invoke potentially uncomfortable or triggering imagery. In much of the base
|
||||||
|
class code, it is literally the action being taken, as Doom is indeed a violent
|
||||||
|
game. In these cases it is entirely normal to use such verbs. An example of
|
||||||
|
when this is entirely wasteful is ZDoom's garbage collector (which is exposed
|
||||||
|
with different naming conventions) in which the flag for objects marked for
|
||||||
|
finalization upon the next collection cycle is named `EuthanizeMe`. This kind
|
||||||
|
of wording is certainly jocular and potentially amusing, but a 'funny' name
|
||||||
|
such as this serves no real purpose, and could easily be re-worded to prevent
|
||||||
|
potential discomfort.
|
||||||
|
|
||||||
|
Members are prefixed with `m_` in order to defuse potential clashes with local
|
||||||
|
variables, since case sensitivity cannot defuse them. The alternative to this
|
||||||
|
is to prefix all member variable accesses with `self.`. However, this is
|
||||||
|
potentially excessive and is not entirely productive in writing short and
|
||||||
|
readable examples. This also provides a layer of forward compatibility, as
|
||||||
|
ZDoom does not use `m_` prefixes anywhere within its code. For the opposite
|
||||||
|
reason, as structure types cannot inherit, there is no need to prefix their
|
||||||
|
members, and so this prefix is omitted within them.
|
||||||
|
|
||||||
|
## Layout Conventions
|
||||||
|
|
||||||
|
Use 3 spaces for indentation. Indent at each block, but do not indent `case`
|
||||||
|
labels. Align all code to 80 columns.
|
||||||
|
|
||||||
|
Write only one statement or declaration per line, except in the case of
|
||||||
|
multiple-assignment operations, in which case pairing all of the related
|
||||||
|
declarations and the statement on the same line is allowed as long as it does
|
||||||
|
not exceed 80 columns.
|
||||||
|
|
||||||
|
Always add one blank line between separate method definitions, and between
|
||||||
|
member declarations and member definitions. Add one blank line between local
|
||||||
|
variable declarations and statements, unless specified otherwise. Add one blank
|
||||||
|
line between conditional statements, except the `else` block of an `if`
|
||||||
|
statement.
|
||||||
|
|
||||||
|
Do not place a space before the parentheses of a conditional or loop statement
|
||||||
|
such as `if` or `for`. Always write `if()` and not `if ()`.
|
||||||
|
|
||||||
|
Always place opening braces on their own line. Using braces is not necessary
|
||||||
|
when there is a single sub-statement, for instance with `if(x) y = z;`.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The convention of 3 spaces for indentation comes from [Eternity Engine's style
|
||||||
|
guideline.][1] There is no other reason for this decision, other than it is
|
||||||
|
pleasing to the eye while not being excessive. The indentation and blank line
|
||||||
|
rules are generally the same as the majority of C-like language style
|
||||||
|
guidelines.
|
||||||
|
|
||||||
|
Alignment to 80 columns is for the purpose of reading the raw documentation
|
||||||
|
text under standard size Linux terminals. This is useful, for instance, when
|
||||||
|
reading diff files under the `git` console client. This guideline can generally
|
||||||
|
be ignored outside of this documentation.
|
||||||
|
|
||||||
|
Writing multiple-assignment operations all on one line serves the purpose of
|
||||||
|
grouping all of the relevant information together. In most languages with
|
||||||
|
multiple assignment, you are able to do the declaration and assignment in one
|
||||||
|
line, so this crudely mirrors a more well implemented language syntax.
|
||||||
|
|
||||||
|
Placing opening braces on their own line greatly increases code readability,
|
||||||
|
especially for people hard of sight. Other styles make it easy to confuse where
|
||||||
|
a block begins and create a less clear visual line between the start and end.
|
||||||
|
The purpose of this is to increase readability of this documentation, and not
|
||||||
|
to make code look more pleasing.
|
||||||
|
|
||||||
|
[1]: https://github.com/team-eternity/eternity/blob/master/docs/ee_style_guide.md
|
||||||
|
|
||||||
|
## Commenting Conventions
|
||||||
|
|
||||||
|
Do not use block comments, except for the purpose of example or code that will
|
||||||
|
intentionally not work. Comments may be placed anywhere except at the end of
|
||||||
|
the opening line of a conditional or loop statement, the opening brace of a
|
||||||
|
block, or the ending brace of a block. Always use proper case and punctuation
|
||||||
|
when writing comments. Always put one space between the comment delimiter and
|
||||||
|
comment text.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Block comments are mostly an adage of old programming languages made to be
|
||||||
|
printed on paper. In modern times they are most useful for commenting out large
|
||||||
|
blocks of code. They are rather clumsy to format well, and so single-line
|
||||||
|
comments are to be used instead of them. One could argue that if a consistent
|
||||||
|
formatting style was added, this would not be a problem. However, it is
|
||||||
|
generally easier and more readable to just use line comments.
|
||||||
|
|
||||||
|
## Language Guidelines
|
||||||
|
|
||||||
|
Use `let` declarations when the type of the object will be obvious from what it
|
||||||
|
is assigned. Do not use them if it is not obvious, or in example when it is
|
||||||
|
necessary to proclaim the type to make reading easier.
|
||||||
|
|
||||||
|
Don't use integer types except for `int` except in example. Similarly, do not
|
||||||
|
use float types except for `double` except in example.
|
||||||
|
|
||||||
|
No restrictions are placed on the usage of parentheses. Always place spaces
|
||||||
|
between the operands of binary expressions (`1 + 1`) but never unary
|
||||||
|
expressions (`-5`.)
|
||||||
|
|
||||||
|
Do not place semicolons at the end of `enum` or `struct` definitions. However, always place commas at the end of the last enumeration variant.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Integer and floating-point types other than `int` and `double` are primarily
|
||||||
|
for internal use. They can be used by user types, but often it's not necessary
|
||||||
|
and can be harmful.
|
||||||
|
|
||||||
|
Placing semicolons at the end of top-level items is not meant to be used by end
|
||||||
|
users. Its main purpose is to make ZScript easier to port from C++. On the
|
||||||
|
other hand, placing a comma at the end of the last enumeration in a set is a
|
||||||
|
common practice, as it allows the user to place more variants without touching
|
||||||
|
much.
|
||||||
|
|
||||||
|
<!-- EOF -->
|
|
@ -5,6 +5,7 @@
|
||||||
* [Classes](glossary-Classes.md)
|
* [Classes](glossary-Classes.md)
|
||||||
* [Concepts](glossary-Concepts.md)
|
* [Concepts](glossary-Concepts.md)
|
||||||
* [Structures](glossary-Structures.md)
|
* [Structures](glossary-Structures.md)
|
||||||
|
* [Style](glossary-Style.md)
|
||||||
* [Versions](glossary-Versions.md)
|
* [Versions](glossary-Versions.md)
|
||||||
|
|
||||||
<!-- end -->
|
<!-- end -->
|
||||||
|
|
|
@ -22,7 +22,7 @@ creating within the language.
|
||||||
|
|
||||||
All classes inherit from other classes. The base class can be set within the
|
All classes inherit from other classes. The base class can be set within the
|
||||||
class header, but if it is not the class will automatically inherit from
|
class header, but if it is not the class will automatically inherit from
|
||||||
Object.
|
`Object`.
|
||||||
|
|
||||||
Classes are subject to Scoping. They are also implicitly reference values, and
|
Classes are subject to Scoping. They are also implicitly reference values, and
|
||||||
therefore can be null. Use `new` to instantiate a new class object.
|
therefore can be null. Use `new` to instantiate a new class object.
|
||||||
|
@ -64,23 +64,38 @@ In place of the class header.
|
||||||
## Example: Class headers
|
## Example: Class headers
|
||||||
|
|
||||||
```
|
```
|
||||||
class MyCoolObject // automatically inherits Object
|
// Automatically inherits Object, similar to the "actor" keyword in DECORATE.
|
||||||
|
class MyCoolObject
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyCoolScopedObject play // has Play scope
|
// Equivalent to the above.
|
||||||
|
class MyCoolObjectExplicit : Object
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyCoolThinker : Thinker // inherits Thinker
|
// Has "Play" scope.
|
||||||
|
class MyCoolScopedObject play
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inherits Thinker and can override functions on it.
|
||||||
|
class MyCoolThinker : Thinker
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some actor.
|
||||||
|
class OtherActor : Actor
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replaces "OtherActor."
|
||||||
class MyCoolActor : Actor replaces OtherActor
|
class MyCoolActor : Actor replaces OtherActor
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyCoolInterface abstract // can only be inherited
|
// Can only be inherited.
|
||||||
|
class MyCoolInterface abstract
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -92,8 +107,10 @@ Basic class definition with a member variable and member function.
|
||||||
```
|
```
|
||||||
class BasicClass
|
class BasicClass
|
||||||
{
|
{
|
||||||
|
// "m_Thing" is attached to any "instance" of BasicClass.
|
||||||
int m_Thing;
|
int m_Thing;
|
||||||
|
|
||||||
|
// Changes "m_Thing" to 500 on an instance of BasicClass.
|
||||||
void ChangeThing()
|
void ChangeThing()
|
||||||
{
|
{
|
||||||
m_Thing = 500;
|
m_Thing = 500;
|
||||||
|
@ -104,11 +121,12 @@ class BasicClass
|
||||||
Alternate syntax usage.
|
Alternate syntax usage.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// This class spans from this point to the end of the file.
|
||||||
class TheWholeFileIsAClassOhNo;
|
class TheWholeFileIsAClassOhNo;
|
||||||
|
|
||||||
int m_MyMember;
|
int m_MyMember;
|
||||||
|
|
||||||
// end of file
|
// End of file, end of class.
|
||||||
```
|
```
|
||||||
|
|
||||||
# Class Flags
|
# Class Flags
|
||||||
|
@ -167,15 +185,19 @@ A class with some properties.
|
||||||
```
|
```
|
||||||
class MyCoolActor : Actor
|
class MyCoolActor : Actor
|
||||||
{
|
{
|
||||||
|
// You can set defined properties in a "default" block like in DECORATE.
|
||||||
|
// This will also be available in DECORATE code that inherits your class!
|
||||||
default
|
default
|
||||||
{
|
{
|
||||||
MyCoolActor.MyCoolMember 5000;
|
MyCoolActor.MyCoolMember 5000;
|
||||||
MyCoolActor.MyCoolMemberList 501, 502;
|
MyCoolActor.MyCoolMemberList 501, 502;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Declare some members.
|
||||||
int m_MyCoolMember;
|
int m_MyCoolMember;
|
||||||
int m_CoolMember1, m_CoolMember2;
|
int m_CoolMember1, m_CoolMember2;
|
||||||
|
|
||||||
|
// Declare some properties attached to our members.
|
||||||
property MyCoolMember: m_MyCoolMember;
|
property MyCoolMember: m_MyCoolMember;
|
||||||
property MyCoolMemberList: m_CoolMember1, m_CoolMember2;
|
property MyCoolMemberList: m_CoolMember1, m_CoolMember2;
|
||||||
}
|
}
|
||||||
|
@ -219,18 +241,25 @@ A class with some flags.
|
||||||
```
|
```
|
||||||
class MyCoolActorWithFlags : Actor
|
class MyCoolActorWithFlags : Actor
|
||||||
{
|
{
|
||||||
|
// You can set defined flag in a "default" block like in DECORATE.
|
||||||
|
// This will also be available in DECORATE code that inherits your class!
|
||||||
|
// Hey, those sentences sounded familiar...
|
||||||
default
|
default
|
||||||
{
|
{
|
||||||
+MYCOOLACTORWITHFLAGS.THIS_ONE_IS_ON
|
+MYCOOLACTORWITHFLAGS.THIS_ONE_IS_ON
|
||||||
-MYCOOLACTORWITHFLAGS.THIS_ONE_IS_OFF
|
-MYCOOLACTORWITHFLAGS.THIS_ONE_IS_OFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Declare a flag field for all of the flags. This can hold up to 32 flags.
|
||||||
int m_Flags;
|
int m_Flags;
|
||||||
|
|
||||||
flagdef This_One_Is_On: m_Flags, 0;
|
// Declare the flags, one at a time...
|
||||||
flagdef This_One_Is_Off: m_Flags, 1;
|
flagdef THIS_ONE_IS_ON: m_Flags, 0;
|
||||||
flagdef This_One_Aliases_On: m_Flags, 0;
|
flagdef THIS_ONE_IS_OFF: m_Flags, 1;
|
||||||
|
flagdef THIS_ONE_ALIASES_ON: m_Flags, 0;
|
||||||
|
|
||||||
|
// Unnecessary, since you can just access it directly, but this demonstrates
|
||||||
|
// how declared flags can be used in methods.
|
||||||
bool CheckIfOnIsOn()
|
bool CheckIfOnIsOn()
|
||||||
{
|
{
|
||||||
return bTHIS_ONE_IS_ON;
|
return bTHIS_ONE_IS_ON;
|
||||||
|
|
|
@ -19,10 +19,12 @@ type.
|
||||||
|
|
||||||
## Example: Constant definitions
|
## Example: Constant definitions
|
||||||
|
|
||||||
Making an integer constant from a double.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
const MY_COOL_INT = int(777.7777);
|
// Making a regular integer constant.
|
||||||
|
const MY_COOL_NUMBER = 777;
|
||||||
|
|
||||||
|
// Making an integer constant from a double.
|
||||||
|
const MY_COOL_NUMBER_FROM_BEYOND = int(777.7777);
|
||||||
```
|
```
|
||||||
|
|
||||||
# Static array definitions
|
# Static array definitions
|
||||||
|
|
|
@ -35,28 +35,24 @@ Identifier $[ = Expression]$
|
||||||
|
|
||||||
## Example: Enumeration definitions
|
## Example: Enumeration definitions
|
||||||
|
|
||||||
Basic enumeration.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// Basic enumeration.
|
||||||
enum MyCoolEnum
|
enum MyCoolEnum
|
||||||
{
|
{
|
||||||
A, // has value int(0)
|
A_THING, // Has value int(0) ...
|
||||||
B, // 1 ...
|
BEES, // ... 1 ...
|
||||||
C, // 2 ...
|
CALCIUM, // ... 2 ...
|
||||||
D // and 3
|
DEXTROSE, // ... and 3.
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Less trivial example.
|
// Less trivial example.
|
||||||
|
|
||||||
```
|
|
||||||
enum MyCoolerEnum : int16
|
enum MyCoolerEnum : int16
|
||||||
{
|
{
|
||||||
A = 500, // has value int16(500)
|
A = 500, // Has value int16(500),
|
||||||
B, // 501
|
B, // 501,
|
||||||
C = 200,
|
C = 200,
|
||||||
D, // 201
|
D, // 201,
|
||||||
E, // 202
|
E, // and 202.
|
||||||
};
|
}
|
||||||
```
|
```
|
||||||
<!-- EOF -->
|
<!-- EOF -->
|
||||||
|
|
|
@ -56,9 +56,9 @@ character. Character escapes include:
|
||||||
| `\xnn` or `\Xnn` | Byte `0xnn`. |
|
| `\xnn` or `\Xnn` | Byte `0xnn`. |
|
||||||
| `\nnn` | Byte `0nnn` (octal.) |
|
| `\nnn` | Byte `0nnn` (octal.) |
|
||||||
|
|
||||||
To quote [cppreference](https://en.cppreference.com/w/cpp/language/escape), "of
|
To quote [cppreference][1], "of the octal escape sequences, `\0` is the most
|
||||||
the octal escape sequences, `\0` is the most useful because it represents the
|
useful because it represents the terminating null character in null-terminated
|
||||||
terminating null character in null-terminated strings."
|
strings."
|
||||||
|
|
||||||
String literals, also like C and C++, will be concatenated when put directly
|
String literals, also like C and C++, will be concatenated when put directly
|
||||||
next to each other. For example, this:
|
next to each other. For example, this:
|
||||||
|
@ -69,6 +69,8 @@ next to each other. For example, this:
|
||||||
|
|
||||||
Will be parsed as a single string literal with the text `"text 1text 2"`.
|
Will be parsed as a single string literal with the text `"text 1text 2"`.
|
||||||
|
|
||||||
|
[1]: https://en.cppreference.com/w/cpp/language/escape
|
||||||
|
|
||||||
## Class type literals
|
## Class type literals
|
||||||
|
|
||||||
Class type literals take the same form as string literals, but do note that
|
Class type literals take the same form as string literals, but do note that
|
||||||
|
|
|
@ -22,10 +22,19 @@ $[Member-declaration-flags...]$ Type Variable-name $[ , Variable-name]$... ;
|
||||||
Some basic member variables.
|
Some basic member variables.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// An integer. Visible to and modifiable by everything.
|
||||||
int m_MyCoolInt;
|
int m_MyCoolInt;
|
||||||
|
|
||||||
|
// Three separate integers, defined short-hand.
|
||||||
int m_CoolInt1, m_CoolInt2, m_CoolInt3;
|
int m_CoolInt1, m_CoolInt2, m_CoolInt3;
|
||||||
|
|
||||||
|
// Ten integers in one variable.
|
||||||
int[10] m_CoolIntArray;
|
int[10] m_CoolIntArray;
|
||||||
|
|
||||||
|
// Can only be seen by this type.
|
||||||
private int m_CoolPrivateInt;
|
private int m_CoolPrivateInt;
|
||||||
|
|
||||||
|
// Read-only (part of the class data, can only be seen by descendant types.
|
||||||
protected meta int m_CoolMetaInt;
|
protected meta int m_CoolMetaInt;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -57,31 +57,25 @@ Or, the entire list may simply be `void` or empty.
|
||||||
|
|
||||||
## Example: Method argument lists
|
## Example: Method argument lists
|
||||||
|
|
||||||
With the function:
|
|
||||||
|
|
||||||
```
|
|
||||||
void Fn(int one, int two, int a = 0, int b = 0);
|
|
||||||
```
|
```
|
||||||
|
// With the function:
|
||||||
|
void DoSomething(int one, int two, int a = 0, int b = 0);
|
||||||
|
|
||||||
One could do the following:
|
// One could do the following:
|
||||||
|
DoSomething(4, 5);
|
||||||
|
DoSomething(5, 6, 7);
|
||||||
|
DoSomething(6, 7, 8, 9);
|
||||||
|
|
||||||
```
|
// Or using named default arguments,
|
||||||
Fn(4, 5);
|
DoSomething(5, 6, a: 7);
|
||||||
Fn(5, 6, 7);
|
|
||||||
Fn(6, 7, 8, 9);
|
|
||||||
```
|
|
||||||
|
|
||||||
Or using named default arguments,
|
// Equivalent to:
|
||||||
|
DoSomething(5, 6, 7);
|
||||||
|
|
||||||
```
|
// And more examples:
|
||||||
Fn(5, 6, a: 7);
|
DoSomething(6, 7, b: 8);
|
||||||
Fn(6, 7, b: 8);
|
DoSomething(7, 8, a: 9, b: 10);
|
||||||
Fn(7, 8, a: 9, b: 10);
|
DoSomething(7, 8, 9, 10);
|
||||||
|
|
||||||
// equivalent to:
|
|
||||||
Fn(5, 6, 7);
|
|
||||||
// (no equivalent, must use above)
|
|
||||||
Fn(7, 8, 9, 10);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Method Definition Flags
|
# Method Definition Flags
|
||||||
|
|
|
@ -53,12 +53,13 @@ Expression ;
|
||||||
|
|
||||||
## Example: Expression statements
|
## Example: Expression statements
|
||||||
|
|
||||||
Some basic expressions.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// Some basic expressions.
|
||||||
MyCoolFunction(5, 4);
|
MyCoolFunction(5, 4);
|
||||||
m_MyCoolMember = 500;
|
m_MyCoolMember = 500;
|
||||||
5 * 5; // does nothing of course, but valid
|
|
||||||
|
// Does nothing, of course, but valid.
|
||||||
|
5 * 5;
|
||||||
```
|
```
|
||||||
|
|
||||||
# Conditional Statements
|
# Conditional Statements
|
||||||
|
@ -72,16 +73,14 @@ if ( Expression ) Statement $[ else Statement]$
|
||||||
|
|
||||||
## Example: Conditional statements
|
## Example: Conditional statements
|
||||||
|
|
||||||
Simple conditional.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// Simple conditional.
|
||||||
|
|
||||||
if(a)
|
if(a)
|
||||||
B();
|
B();
|
||||||
```
|
|
||||||
|
|
||||||
Simple conditional, with else statement and a block.
|
// Simple conditional, with else statement and a block.
|
||||||
|
|
||||||
```
|
|
||||||
if(a)
|
if(a)
|
||||||
{
|
{
|
||||||
B();
|
B();
|
||||||
|
@ -102,17 +101,23 @@ switch ( Expression ) Statement
|
||||||
|
|
||||||
## Example: Switch statements
|
## Example: Switch statements
|
||||||
|
|
||||||
A switch demonstrating fall-through and default cases.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// A switch demonstrating fall-through and default cases.
|
||||||
|
|
||||||
switch(a)
|
switch(a)
|
||||||
{
|
{
|
||||||
case 500: Console.PrintF("a is 500"); break;
|
case 500:
|
||||||
case 501: Console.PrintF("a is 501"); // falls through to next case
|
Console.PrintF("a is 500");
|
||||||
case 502: Console.PrintF("a is 501 or 502"); break;
|
break;
|
||||||
|
case 501:
|
||||||
|
Console.PrintF("a is 501");
|
||||||
|
// Falls through to the next case.
|
||||||
|
case 502:
|
||||||
|
Console.PrintF("a is 501 or 502");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Console.PrintF("not sure what a is!");
|
Console.PrintF("not sure what a is!");
|
||||||
// break is implied here
|
// "break" is implied here.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -185,49 +190,51 @@ return $[Expression $[ , Expression]$...]$ ;
|
||||||
|
|
||||||
## Example: Control flow statements
|
## Example: Control flow statements
|
||||||
|
|
||||||
Use of `continue`.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// Use of "continue."
|
||||||
for(int i = 0; i < 50; i++)
|
for(int i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
if(i == 25) continue; // don't do anything on 25!
|
// Don't do anything when "i" is 25.
|
||||||
|
if(i == 25)
|
||||||
|
continue;
|
||||||
|
|
||||||
DoThing(i);
|
DoThing(i);
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Use of `break`.
|
// Use of "break."
|
||||||
|
|
||||||
```
|
|
||||||
for(int i = 0; i < 50; i++)
|
for(int i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
if(i == 25) break; // exit the loop at 25!
|
// "break" when "i" is 25.
|
||||||
|
if(i == 25)
|
||||||
|
break;
|
||||||
|
|
||||||
DoThing(i);
|
DoThing(i);
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Use of `return` in various contexts.
|
// Use of `return` in various contexts.
|
||||||
|
|
||||||
```
|
|
||||||
void ReturnsNothing()
|
void ReturnsNothing()
|
||||||
{
|
{
|
||||||
if(m_Thing != 50) return; // exit early if m_Thing isn't 50.
|
// Exit early if "m_Thing" isn't 50.
|
||||||
|
if(m_Thing != 50)
|
||||||
|
return;
|
||||||
|
|
||||||
DoThing(m_Thing);
|
DoThing(m_Thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReturnsInt()
|
int ReturnsInt()
|
||||||
{
|
{
|
||||||
|
// "m_Thing" is 50, so return 50.
|
||||||
if(m_Thing == 50)
|
if(m_Thing == 50)
|
||||||
return 50; // m_thing is 50, so return 50.
|
return 50;
|
||||||
|
|
||||||
return 0; // must have a return eventually
|
// Must have a return, eventually.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int, int ReturnsTwoInts()
|
int, int ReturnsTwoInts()
|
||||||
{
|
{
|
||||||
return 1, 2; // returns 1 and 2.
|
// Returns 1 and 2.
|
||||||
|
return 1, 2;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -264,12 +271,9 @@ Note that the surrounding brackets are literal and not an optional element.
|
||||||
|
|
||||||
## Example: Multi-assignment statements
|
## Example: Multi-assignment statements
|
||||||
|
|
||||||
Getting the actor out of `A_SpawnItemEx`.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Actor mo;
|
// Getting the actor out of "A_SpawnItemEx."
|
||||||
bool spawned;
|
Actor mo; bool spawned; [spawned, mo] = A_SpawnItemEx("MyCoolActor");
|
||||||
[spawned, mo] = A_SpawnItemEx("MyCoolActor");
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Static Array Statements
|
# Static Array Statements
|
||||||
|
|
|
@ -34,9 +34,8 @@ Optionally followed by a semicolon.
|
||||||
|
|
||||||
## Example: Structure definitions
|
## Example: Structure definitions
|
||||||
|
|
||||||
Simple structure.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
// Simple structure.
|
||||||
struct MyCoolStructure
|
struct MyCoolStructure
|
||||||
{
|
{
|
||||||
int X;
|
int X;
|
||||||
|
|
|
@ -15,7 +15,7 @@ def filter_emit r
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_toc_areas f
|
def find_toc_areas f
|
||||||
re = /^(<!-- inter-toc ([^\s]+)\s+-->)(?:.|\n)*?(<!-- end -->)/i
|
re = /^(<!-- inter-toc\s*([^\s]+)\s*-->)(?:.|\n)*?(<!-- end -->)/i
|
||||||
f.to_enum(:scan, re).map{$~}
|
f.to_enum(:scan, re).map{$~}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue