Reorganize repo
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.luau text eol=lf
|
9
.github/ISSUE_TEMPLATE/BUG-REPORT.md
vendored
|
@ -1,22 +1,25 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: File a bug report for any behavior that you believe is unintentional or problematic
|
||||
title: "[BUG]"
|
||||
title: ""
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
## Describe the bug
|
||||
|
||||
Put a clear and concise description of what the bug is. This should be short and to the point, not to exceed more than a paragraph. Put the details inside your reproduction steps.
|
||||
|
||||
## Reproduction
|
||||
|
||||
Make an easy-to-follow guide on how to reproduce it. Does it happen all the time? Will specific features affect reproduction? All these questions should be answered for a good issue.
|
||||
|
||||
This is a good place to put rbxl files or scripts that help explain your reproduction steps.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
What you expect to happen
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
What actually happens
|
7
.github/ISSUE_TEMPLATE/DOCUMENTATION.md
vendored
|
@ -1,14 +1,15 @@
|
|||
---
|
||||
name: Documentation
|
||||
about: Open an issue to add, change, or otherwise modify any part of the documentation.
|
||||
title: "[DOCS]"
|
||||
title: ""
|
||||
labels: documentation
|
||||
assignees: ''
|
||||
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
## Which Sections Does This Issue Cover?
|
||||
|
||||
[Put sections (e.g. Query Concepts), page links, etc as necessary]
|
||||
|
||||
## What Needs To Change?
|
||||
|
||||
What specifically needs to change and what suggestions do you have to change it?
|
6
.github/ISSUE_TEMPLATE/FEATURE-REQUEST.md
vendored
|
@ -1,10 +1,9 @@
|
|||
---
|
||||
name: Feature Request
|
||||
about: File a feature request for something you believe should be added to Jecs
|
||||
title: "[FEATURE]"
|
||||
title: ""
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
## Describe your Feature
|
||||
|
@ -22,6 +21,7 @@ What other alternative implementations or otherwise relevant information is impo
|
|||
## Considerations
|
||||
|
||||
Some questions that need to be answered include the following:
|
||||
|
||||
- Will old code break in response to this feature?
|
||||
- What are the performance impacts with this feature (if any)?
|
||||
- How is it useful to include?
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
syntax = "All"
|
||||
column_width = 120
|
||||
line_endings = "Unix"
|
||||
indent_type = "Tabs"
|
||||
indent_width = 4
|
||||
quote_style = "ForceDouble"
|
||||
quote_style = "AutoPreferDouble"
|
||||
call_parentheses = "Always"
|
||||
space_after_function_names = "Never"
|
||||
collapse_simple_statement = "Never"
|
||||
syntax = "Luau"
|
||||
|
||||
[sort_requires]
|
||||
enabled = true
|
|
@ -1,5 +1,5 @@
|
|||
local jecs = require("@jecs")
|
||||
local mirror = require("../mirror/init")
|
||||
local mirror = require("@mirror")
|
||||
|
||||
type i53 = number
|
||||
|
||||
|
|
BIN
coverage/amber.png
Normal file
After Width: | Height: | Size: 141 B |
1
coverage/cmd_line
Normal file
|
@ -0,0 +1 @@
|
|||
genhtml coverage.out --output-directory=coverage --synthesize-missing --ignore-errors source
|
BIN
coverage/emerald.png
Normal file
After Width: | Height: | Size: 141 B |
1073
coverage/gcov.css
Normal file
BIN
coverage/glass.png
Normal file
After Width: | Height: | Size: 167 B |
129
coverage/index-sort-f.html
Normal file
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>LCOV - coverage.out</title>
|
||||
<link rel="stylesheet" type="text/css" href="gcov.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table width="100%" border=0 cellspacing=0 cellpadding=0>
|
||||
<tr><td class="title">LCOV - code coverage report</td></tr>
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
|
||||
<tr>
|
||||
<td width="100%">
|
||||
<table cellpadding=1 border=0 width="100%">
|
||||
<tr>
|
||||
<td width="10%" class="headerItem">Current view:</td>
|
||||
<td width="10%" class="headerValue">top level</td>
|
||||
<td width="5%"></td>
|
||||
<td width="5%"></td>
|
||||
<td width="5%" class="headerCovTableHead">Coverage</td>
|
||||
<td width="5%" class="headerCovTableHead" title="Covered + Uncovered code">Total</td>
|
||||
<td width="5%" class="headerCovTableHead" title="Exercised code only">Hit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="headerItem">Test:</td>
|
||||
<td class="headerValue">coverage.out</td>
|
||||
<td></td>
|
||||
<td class="headerItem">Lines:</td>
|
||||
<td class="headerCovTableEntryMed">80.3 %</td>
|
||||
<td class="headerCovTableEntry">3222</td>
|
||||
<td class="headerCovTableEntry">2587</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="headerItem">Test Date:</td>
|
||||
<td class="headerValue">2025-03-27 02:15:11</td>
|
||||
<td></td>
|
||||
<td class="headerItem">Functions:</td>
|
||||
<td class="headerCovTableEntryLo">65.3 %</td>
|
||||
<td class="headerCovTableEntry">219</td>
|
||||
<td class="headerCovTableEntry">143</td>
|
||||
</tr>
|
||||
<tr><td><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
</table>
|
||||
|
||||
<center>
|
||||
<table width="80%" cellpadding=1 cellspacing=1 border=0>
|
||||
|
||||
<tr>
|
||||
<td width="40%"><br></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tableHead" rowspan=2>Directory <span title="Click to sort table by file name" class="tableHeadSort"><a href="index.html"><img src="updown.png" width=10 height=14 alt="Sort by file name" title="Click to sort table by file name" border=0></a></span></td>
|
||||
<td class="tableHead" colspan=4>Line Coverage <span title="Click to sort table by line coverage" class="tableHeadSort"><a href="index-sort-l.html"><img src="updown.png" width=10 height=14 alt="Sort by line coverage" title="Click to sort table by line coverage" border=0></a></span></td>
|
||||
<td class="tableHead" colspan=3>Function Coverage <span title="Click to sort table by function coverage" class="tableHeadSort"><img src="glass.png" width=10 height=14 alt="Sort by function coverage" title="Click to sort table by function coverage" border=0></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableHead" colspan=2> Rate</td>
|
||||
<td class="tableHead"> Total</td>
|
||||
<td class="tableHead"> Hit</td>
|
||||
<td class="tableHead"> Rate</td>
|
||||
<td class="tableHead"> Total</td>
|
||||
<td class="tableHead"> Hit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="jecs/C:/Users/Marcus/Documents/packages/jecs/index.html">jecs/C:/Users/Marcus/Documents/packages/jecs</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="ruby.png" width=72 height=10 alt="71.7%"><img src="snow.png" width=28 height=10 alt="71.7%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerLo">71.7 %</td>
|
||||
<td class="coverNumDflt">1487</td>
|
||||
<td class="coverNumDflt">1066</td>
|
||||
<td class="coverPerLo">53.6 %</td>
|
||||
<td class="coverNumDflt">97</td>
|
||||
<td class="coverNumDflt">52</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="jecs/tools/C:/Users/Marcus/Documents/packages/jecs/tools/index.html">jecs/tools/C:/Users/Marcus/Documents/packages/jecs/tools</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="ruby.png" width=63 height=10 alt="63.0%"><img src="snow.png" width=37 height=10 alt="63.0%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerLo">63.0 %</td>
|
||||
<td class="coverNumDflt">508</td>
|
||||
<td class="coverNumDflt">320</td>
|
||||
<td class="coverPerLo">63.6 %</td>
|
||||
<td class="coverNumDflt">55</td>
|
||||
<td class="coverNumDflt">35</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="mnt/c/Users/Marcus/Documents/packages/jecs/test/test/index.html">/mnt/c/Users/Marcus/Documents/packages/jecs/test/test</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="emerald.png" width=98 height=10 alt="97.9%"><img src="snow.png" width=2 height=10 alt="97.9%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerHi">97.9 %</td>
|
||||
<td class="coverNumDflt">1227</td>
|
||||
<td class="coverNumDflt">1201</td>
|
||||
<td class="coverPerMed">83.6 %</td>
|
||||
<td class="coverNumDflt">67</td>
|
||||
<td class="coverNumDflt">56</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<br>
|
||||
|
||||
<table width="100%" border=0 cellspacing=0 cellpadding=0>
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
<tr><td class="versionInfo">Generated by: <a href="https://github.com//linux-test-project/lcov">LCOV version 2.0-1</a></td></tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
129
coverage/index-sort-l.html
Normal file
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>LCOV - coverage.out</title>
|
||||
<link rel="stylesheet" type="text/css" href="gcov.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table width="100%" border=0 cellspacing=0 cellpadding=0>
|
||||
<tr><td class="title">LCOV - code coverage report</td></tr>
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
|
||||
<tr>
|
||||
<td width="100%">
|
||||
<table cellpadding=1 border=0 width="100%">
|
||||
<tr>
|
||||
<td width="10%" class="headerItem">Current view:</td>
|
||||
<td width="10%" class="headerValue">top level</td>
|
||||
<td width="5%"></td>
|
||||
<td width="5%"></td>
|
||||
<td width="5%" class="headerCovTableHead">Coverage</td>
|
||||
<td width="5%" class="headerCovTableHead" title="Covered + Uncovered code">Total</td>
|
||||
<td width="5%" class="headerCovTableHead" title="Exercised code only">Hit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="headerItem">Test:</td>
|
||||
<td class="headerValue">coverage.out</td>
|
||||
<td></td>
|
||||
<td class="headerItem">Lines:</td>
|
||||
<td class="headerCovTableEntryMed">80.3 %</td>
|
||||
<td class="headerCovTableEntry">3222</td>
|
||||
<td class="headerCovTableEntry">2587</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="headerItem">Test Date:</td>
|
||||
<td class="headerValue">2025-03-27 02:15:11</td>
|
||||
<td></td>
|
||||
<td class="headerItem">Functions:</td>
|
||||
<td class="headerCovTableEntryLo">65.3 %</td>
|
||||
<td class="headerCovTableEntry">219</td>
|
||||
<td class="headerCovTableEntry">143</td>
|
||||
</tr>
|
||||
<tr><td><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
</table>
|
||||
|
||||
<center>
|
||||
<table width="80%" cellpadding=1 cellspacing=1 border=0>
|
||||
|
||||
<tr>
|
||||
<td width="40%"><br></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tableHead" rowspan=2>Directory <span title="Click to sort table by file name" class="tableHeadSort"><a href="index.html"><img src="updown.png" width=10 height=14 alt="Sort by file name" title="Click to sort table by file name" border=0></a></span></td>
|
||||
<td class="tableHead" colspan=4>Line Coverage <span title="Click to sort table by line coverage" class="tableHeadSort"><img src="glass.png" width=10 height=14 alt="Sort by line coverage" title="Click to sort table by line coverage" border=0></span></td>
|
||||
<td class="tableHead" colspan=3>Function Coverage <span title="Click to sort table by function coverage" class="tableHeadSort"><a href="index-sort-f.html"><img src="updown.png" width=10 height=14 alt="Sort by function coverage" title="Click to sort table by function coverage" border=0></a></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableHead" colspan=2> Rate</td>
|
||||
<td class="tableHead"> Total</td>
|
||||
<td class="tableHead"> Hit</td>
|
||||
<td class="tableHead"> Rate</td>
|
||||
<td class="tableHead"> Total</td>
|
||||
<td class="tableHead"> Hit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="jecs/tools/C:/Users/Marcus/Documents/packages/jecs/tools/index.html">jecs/tools/C:/Users/Marcus/Documents/packages/jecs/tools</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="ruby.png" width=63 height=10 alt="63.0%"><img src="snow.png" width=37 height=10 alt="63.0%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerLo">63.0 %</td>
|
||||
<td class="coverNumDflt">508</td>
|
||||
<td class="coverNumDflt">320</td>
|
||||
<td class="coverPerLo">63.6 %</td>
|
||||
<td class="coverNumDflt">55</td>
|
||||
<td class="coverNumDflt">35</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="jecs/C:/Users/Marcus/Documents/packages/jecs/index.html">jecs/C:/Users/Marcus/Documents/packages/jecs</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="ruby.png" width=72 height=10 alt="71.7%"><img src="snow.png" width=28 height=10 alt="71.7%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerLo">71.7 %</td>
|
||||
<td class="coverNumDflt">1487</td>
|
||||
<td class="coverNumDflt">1066</td>
|
||||
<td class="coverPerLo">53.6 %</td>
|
||||
<td class="coverNumDflt">97</td>
|
||||
<td class="coverNumDflt">52</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="mnt/c/Users/Marcus/Documents/packages/jecs/test/test/index.html">/mnt/c/Users/Marcus/Documents/packages/jecs/test/test</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="emerald.png" width=98 height=10 alt="97.9%"><img src="snow.png" width=2 height=10 alt="97.9%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerHi">97.9 %</td>
|
||||
<td class="coverNumDflt">1227</td>
|
||||
<td class="coverNumDflt">1201</td>
|
||||
<td class="coverPerMed">83.6 %</td>
|
||||
<td class="coverNumDflt">67</td>
|
||||
<td class="coverNumDflt">56</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<br>
|
||||
|
||||
<table width="100%" border=0 cellspacing=0 cellpadding=0>
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
<tr><td class="versionInfo">Generated by: <a href="https://github.com//linux-test-project/lcov">LCOV version 2.0-1</a></td></tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
129
coverage/index.html
Normal file
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>LCOV - coverage.out</title>
|
||||
<link rel="stylesheet" type="text/css" href="gcov.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table width="100%" border=0 cellspacing=0 cellpadding=0>
|
||||
<tr><td class="title">LCOV - code coverage report</td></tr>
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
|
||||
<tr>
|
||||
<td width="100%">
|
||||
<table cellpadding=1 border=0 width="100%">
|
||||
<tr>
|
||||
<td width="10%" class="headerItem">Current view:</td>
|
||||
<td width="10%" class="headerValue">top level</td>
|
||||
<td width="5%"></td>
|
||||
<td width="5%"></td>
|
||||
<td width="5%" class="headerCovTableHead">Coverage</td>
|
||||
<td width="5%" class="headerCovTableHead" title="Covered + Uncovered code">Total</td>
|
||||
<td width="5%" class="headerCovTableHead" title="Exercised code only">Hit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="headerItem">Test:</td>
|
||||
<td class="headerValue">coverage.out</td>
|
||||
<td></td>
|
||||
<td class="headerItem">Lines:</td>
|
||||
<td class="headerCovTableEntryMed">80.3 %</td>
|
||||
<td class="headerCovTableEntry">3222</td>
|
||||
<td class="headerCovTableEntry">2587</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="headerItem">Test Date:</td>
|
||||
<td class="headerValue">2025-03-27 02:15:11</td>
|
||||
<td></td>
|
||||
<td class="headerItem">Functions:</td>
|
||||
<td class="headerCovTableEntryLo">65.3 %</td>
|
||||
<td class="headerCovTableEntry">219</td>
|
||||
<td class="headerCovTableEntry">143</td>
|
||||
</tr>
|
||||
<tr><td><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
</table>
|
||||
|
||||
<center>
|
||||
<table width="80%" cellpadding=1 cellspacing=1 border=0>
|
||||
|
||||
<tr>
|
||||
<td width="40%"><br></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
<td width="8%"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tableHead" rowspan=2>Directory <span title="Click to sort table by file name" class="tableHeadSort"><img src="glass.png" width=10 height=14 alt="Sort by file name" title="Click to sort table by file name" border=0></span></td>
|
||||
<td class="tableHead" colspan=4>Line Coverage <span title="Click to sort table by line coverage" class="tableHeadSort"><a href="index-sort-l.html"><img src="updown.png" width=10 height=14 alt="Sort by line coverage" title="Click to sort table by line coverage" border=0></a></span></td>
|
||||
<td class="tableHead" colspan=3>Function Coverage <span title="Click to sort table by function coverage" class="tableHeadSort"><a href="index-sort-f.html"><img src="updown.png" width=10 height=14 alt="Sort by function coverage" title="Click to sort table by function coverage" border=0></a></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableHead" colspan=2> Rate</td>
|
||||
<td class="tableHead"> Total</td>
|
||||
<td class="tableHead"> Hit</td>
|
||||
<td class="tableHead"> Rate</td>
|
||||
<td class="tableHead"> Total</td>
|
||||
<td class="tableHead"> Hit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="jecs/C:/Users/Marcus/Documents/packages/jecs/index.html">jecs/C:/Users/Marcus/Documents/packages/jecs</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="ruby.png" width=72 height=10 alt="71.7%"><img src="snow.png" width=28 height=10 alt="71.7%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerLo">71.7 %</td>
|
||||
<td class="coverNumDflt">1487</td>
|
||||
<td class="coverNumDflt">1066</td>
|
||||
<td class="coverPerLo">53.6 %</td>
|
||||
<td class="coverNumDflt">97</td>
|
||||
<td class="coverNumDflt">52</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="jecs/tools/C:/Users/Marcus/Documents/packages/jecs/tools/index.html">jecs/tools/C:/Users/Marcus/Documents/packages/jecs/tools</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="ruby.png" width=63 height=10 alt="63.0%"><img src="snow.png" width=37 height=10 alt="63.0%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerLo">63.0 %</td>
|
||||
<td class="coverNumDflt">508</td>
|
||||
<td class="coverNumDflt">320</td>
|
||||
<td class="coverPerLo">63.6 %</td>
|
||||
<td class="coverNumDflt">55</td>
|
||||
<td class="coverNumDflt">35</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="coverFile"><a href="mnt/c/Users/Marcus/Documents/packages/jecs/test/test/index.html">/mnt/c/Users/Marcus/Documents/packages/jecs/test/test</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="emerald.png" width=98 height=10 alt="97.9%"><img src="snow.png" width=2 height=10 alt="97.9%"></td></tr></table>
|
||||
</td>
|
||||
<td class="coverPerHi">97.9 %</td>
|
||||
<td class="coverNumDflt">1227</td>
|
||||
<td class="coverNumDflt">1201</td>
|
||||
<td class="coverPerMed">83.6 %</td>
|
||||
<td class="coverNumDflt">67</td>
|
||||
<td class="coverNumDflt">56</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<br>
|
||||
|
||||
<table width="100%" border=0 cellspacing=0 cellpadding=0>
|
||||
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
||||
<tr><td class="versionInfo">Generated by: <a href="https://github.com//linux-test-project/lcov">LCOV version 2.0-1</a></td></tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
coverage/ruby.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
coverage/snow.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
coverage/updown.png
Normal file
After Width: | Height: | Size: 117 B |
BIN
demo.rbxl
11
jecs.luau
|
@ -52,7 +52,7 @@ export type Archetype = {
|
|||
type ecs_record_t = {
|
||||
archetype: ecs_archetype_t,
|
||||
row: number,
|
||||
dense: i24
|
||||
dense: i24,
|
||||
}
|
||||
|
||||
type ecs_id_record_t = {
|
||||
|
@ -295,10 +295,6 @@ local function ecs_pair_second(world: ecs_world_t, e: i53)
|
|||
return ecs_get_alive(world, obj)
|
||||
end
|
||||
|
||||
local function ecs_component_record(world: ecs_world_t, component: i53)
|
||||
return world.component_index[component]
|
||||
end
|
||||
|
||||
local function query_match(query: ecs_query_data_t,
|
||||
archetype: ecs_archetype_t)
|
||||
local records = archetype.records
|
||||
|
@ -559,10 +555,10 @@ local function id_record_ensure(world: ecs_world_t, id: number): ecs_id_record_t
|
|||
local target = 0
|
||||
local is_pair = ECS_IS_PAIR(id)
|
||||
if is_pair then
|
||||
relation = entity_index_get_alive(entity_index, ECS_PAIR_FIRST(id))
|
||||
relation = entity_index_get_alive(entity_index, ECS_PAIR_FIRST(id)) :: i53
|
||||
assert(relation and entity_index_is_alive(
|
||||
entity_index, relation), ECS_INTERNAL_ERROR)
|
||||
target = entity_index_get_alive(entity_index, ECS_PAIR_SECOND(id))
|
||||
target = entity_index_get_alive(entity_index, ECS_PAIR_SECOND(id)) :: i53
|
||||
assert(target and entity_index_is_alive(
|
||||
entity_index, target), ECS_INTERNAL_ERROR)
|
||||
end
|
||||
|
@ -646,7 +642,6 @@ local function archetype_create(world: ecs_world_t, id_types: { i24 }, ty, prev:
|
|||
local records: { number } = {}
|
||||
local counts: {number} = {}
|
||||
|
||||
local entity_index = world.entity_index
|
||||
local archetype: ecs_archetype_t = {
|
||||
columns = columns,
|
||||
entities = {},
|
||||
|
|
186
mkdocs.yml
|
@ -1,186 +0,0 @@
|
|||
site_name: Jecs
|
||||
site_url: jecs.github.io/jecs
|
||||
repo_name: ukendio/jecs
|
||||
repo_url: https://github.com/ukendio/jecs
|
||||
|
||||
extra:
|
||||
version:
|
||||
provider: mike
|
||||
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: docs/assets/overrides
|
||||
logo: assets/logo
|
||||
favicon: assets/logo-dark.svg
|
||||
palette:
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: fusiondoc-dark
|
||||
toggle:
|
||||
icon: octicons/sun-24
|
||||
title: Switch to light theme
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: fusiondoc-light
|
||||
toggle:
|
||||
icon: octicons/moon-24
|
||||
title: Switch to dark theme
|
||||
font:
|
||||
text: Plus Jakarta Sans
|
||||
code: JetBrains Mono
|
||||
features:
|
||||
- navigation.tabs
|
||||
- navigation.top
|
||||
- navigation.sections
|
||||
- navigation.instant
|
||||
- navigation.indexes
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
icon:
|
||||
repo: octicons/mark-github-16
|
||||
|
||||
extra_css:
|
||||
- assets/theme/fusiondoc.css
|
||||
- assets/theme/colours.css
|
||||
- assets/theme/code.css
|
||||
- assets/theme/paragraph.css
|
||||
- assets/theme/page.css
|
||||
- assets/theme/admonition.css
|
||||
- assets/theme/404.css
|
||||
- assets/theme/api-reference.css
|
||||
- assets/theme/dev-tools.css
|
||||
|
||||
extra_javascript:
|
||||
- assets/scripts/smooth-scroll.js
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Tutorials:
|
||||
- Get Started: tutorials/index.md
|
||||
- Installing Fusion: tutorials/get-started/installing-fusion.md
|
||||
- Developer Tools: tutorials/get-started/developer-tools.md
|
||||
- Getting Help: tutorials/get-started/getting-help.md
|
||||
- Fundamentals:
|
||||
- Scopes: tutorials/fundamentals/scopes.md
|
||||
- Values: tutorials/fundamentals/values.md
|
||||
- Observers: tutorials/fundamentals/observers.md
|
||||
- Computeds: tutorials/fundamentals/computeds.md
|
||||
- Tables:
|
||||
- ForValues: tutorials/tables/forvalues.md
|
||||
- ForKeys: tutorials/tables/forkeys.md
|
||||
- ForPairs: tutorials/tables/forpairs.md
|
||||
- Animation:
|
||||
- Tweens: tutorials/animation/tweens.md
|
||||
- Springs: tutorials/animation/springs.md
|
||||
- Roblox:
|
||||
- Hydration: tutorials/roblox/hydration.md
|
||||
- New Instances: tutorials/roblox/new-instances.md
|
||||
- Parenting: tutorials/roblox/parenting.md
|
||||
- Events: tutorials/roblox/events.md
|
||||
- Change Events: tutorials/roblox/change-events.md
|
||||
- Outputs: tutorials/roblox/outputs.md
|
||||
- References: tutorials/roblox/references.md
|
||||
- Best Practices:
|
||||
- Components: tutorials/best-practices/components.md
|
||||
- Instance Handling: tutorials/best-practices/instance-handling.md
|
||||
- Callbacks: tutorials/best-practices/callbacks.md
|
||||
- State: tutorials/best-practices/state.md
|
||||
- Sharing Values: tutorials/best-practices/sharing-values.md
|
||||
- Error Safety: tutorials/best-practices/error-safety.md
|
||||
- Optimisation: tutorials/best-practices/optimisation.md
|
||||
|
||||
- Examples:
|
||||
- Home: examples/index.md
|
||||
- Cookbook:
|
||||
- examples/cookbook/index.md
|
||||
- Player List: examples/cookbook/player-list.md
|
||||
- Animated Computed: examples/cookbook/animated-computed.md
|
||||
- Fetch Data From Server: examples/cookbook/fetch-data-from-server.md
|
||||
- Light & Dark Theme: examples/cookbook/light-and-dark-theme.md
|
||||
- Button Component: examples/cookbook/button-component.md
|
||||
- Loading Spinner: examples/cookbook/loading-spinner.md
|
||||
- Drag & Drop: examples/cookbook/drag-and-drop.md
|
||||
- API Reference:
|
||||
- api-reference/index.md
|
||||
- General:
|
||||
- Errors: api-reference/general/errors.md
|
||||
- Types:
|
||||
- Contextual: api-reference/general/types/contextual.md
|
||||
- Version: api-reference/general/types/version.md
|
||||
- Members:
|
||||
- Contextual: api-reference/general/members/contextual.md
|
||||
- Safe: api-reference/general/members/safe.md
|
||||
- version: api-reference/general/members/version.md
|
||||
- Memory:
|
||||
- Types:
|
||||
- Scope: api-reference/memory/types/scope.md
|
||||
- ScopedObject: api-reference/memory/types/scopedobject.md
|
||||
- Task: api-reference/memory/types/task.md
|
||||
- Members:
|
||||
- deriveScope: api-reference/memory/members/derivescope.md
|
||||
- doCleanup: api-reference/memory/members/docleanup.md
|
||||
- scoped: api-reference/memory/members/scoped.md
|
||||
- State:
|
||||
- Types:
|
||||
- UsedAs: api-reference/state/types/usedas.md
|
||||
- Computed: api-reference/state/types/computed.md
|
||||
- Dependency: api-reference/state/types/dependency.md
|
||||
- Dependent: api-reference/state/types/dependent.md
|
||||
- For: api-reference/state/types/for.md
|
||||
- Observer: api-reference/state/types/observer.md
|
||||
- StateObject: api-reference/state/types/stateobject.md
|
||||
- Use: api-reference/state/types/use.md
|
||||
- Value: api-reference/state/types/value.md
|
||||
- Members:
|
||||
- Computed: api-reference/state/members/computed.md
|
||||
- ForKeys: api-reference/state/members/forkeys.md
|
||||
- ForPairs: api-reference/state/members/forpairs.md
|
||||
- ForValues: api-reference/state/members/forvalues.md
|
||||
- Observer: api-reference/state/members/observer.md
|
||||
- peek: api-reference/state/members/peek.md
|
||||
- Value: api-reference/state/members/value.md
|
||||
- Roblox:
|
||||
- Types:
|
||||
- Child: api-reference/roblox/types/child.md
|
||||
- PropertyTable: api-reference/roblox/types/propertytable.md
|
||||
- SpecialKey: api-reference/roblox/types/specialkey.md
|
||||
- Members:
|
||||
- Attribute: api-reference/roblox/members/attribute.md
|
||||
- AttributeChange: api-reference/roblox/members/attributechange.md
|
||||
- AttributeOut: api-reference/roblox/members/attributeout.md
|
||||
- Children: api-reference/roblox/members/children.md
|
||||
- Hydrate: api-reference/roblox/members/hydrate.md
|
||||
- New: api-reference/roblox/members/new.md
|
||||
- OnChange: api-reference/roblox/members/onchange.md
|
||||
- OnEvent: api-reference/roblox/members/onevent.md
|
||||
- Out: api-reference/roblox/members/out.md
|
||||
- Ref: api-reference/roblox/members/ref.md
|
||||
- Animation:
|
||||
- Types:
|
||||
- Animatable: api-reference/animation/types/animatable.md
|
||||
- Spring: api-reference/animation/types/spring.md
|
||||
- Tween: api-reference/animation/types/tween.md
|
||||
- Members:
|
||||
- Tween: api-reference/animation/members/tween.md
|
||||
- Spring: api-reference/animation/members/spring.md
|
||||
- Extras:
|
||||
- Home: extras/index.md
|
||||
- Backgrounds: extras/backgrounds.md
|
||||
- Brand Guidelines: extras/brand-guidelines.md
|
||||
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
- attr_list
|
||||
- meta
|
||||
- md_in_html
|
||||
- pymdownx.superfences
|
||||
- pymdownx.betterem
|
||||
- pymdownx.details
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.inlinehilite
|
||||
- toc:
|
||||
permalink: true
|
||||
- pymdownx.highlight:
|
||||
guess_lang: false
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
4464
package-lock.json
generated
Normal file
|
@ -2,5 +2,4 @@
|
|||
wally = "upliftgames/wally@0.3.2"
|
||||
rojo = "rojo-rbx/rojo@7.4.4"
|
||||
stylua = "johnnymorganz/stylua@2.0.1"
|
||||
selene = "kampfkarren/selene@0.27.1"
|
||||
Blink = "1Axen/Blink@0.14.1"
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
std = "roblox"
|
||||
|
||||
[lints]
|
||||
global_usage = "allow"
|
|
@ -1,11 +0,0 @@
|
|||
# Examples
|
||||
|
||||
This folder contains code examples for the Luau/Typescript APIs.
|
||||
|
||||
## Run with Luau
|
||||
To run the examples with Luau, run the following commands from the root of the repository:
|
||||
|
||||
```sh
|
||||
cd examples/luau
|
||||
luau path/to/file.luau
|
||||
```
|
|
@ -1,43 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Position = world:component()
|
||||
local Walking = world:component()
|
||||
local Name = world:component()
|
||||
|
||||
-- Create an entity with name Bob
|
||||
local bob = world:entity()
|
||||
|
||||
-- The set operation finds or creates a component, and sets it.
|
||||
world:set(bob, Position, Vector3.new(10, 20, 30))
|
||||
-- Name the entity Bob
|
||||
world:set(bob, Name, "Bob")
|
||||
-- The add operation adds a component without setting a value. This is
|
||||
-- useful for tags, or when adding a component with its default value.
|
||||
world:add(bob, Walking)
|
||||
|
||||
-- Get the value for the Position component
|
||||
local pos = world:get(bob, Position)
|
||||
print(`\{{pos.X}, {pos.Y}, {pos.Z}\}`)
|
||||
|
||||
-- Overwrite the value of the Position component
|
||||
world:set(bob, Position, Vector3.new(40, 50, 60))
|
||||
|
||||
local alice = world:entity()
|
||||
-- Create another named entity
|
||||
world:set(alice, Name, "Alice")
|
||||
world:set(alice, Position, Vector3.new(10, 20, 30))
|
||||
world:add(alice, Walking)
|
||||
|
||||
-- Remove tag
|
||||
world:remove(alice, Walking)
|
||||
|
||||
-- Iterate all entities with Position
|
||||
for entity, p in world:query(Position) do
|
||||
print(`{entity}: \{{p.X}, {p.Y}, {p.Z}\}`)
|
||||
end
|
||||
|
||||
-- Output:
|
||||
-- {10, 20, 30}
|
||||
-- Alice: {10, 20, 30}
|
||||
-- Bob: {40, 50, 60}
|
|
@ -1,112 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
local pair = jecs.pair
|
||||
local ChildOf = jecs.ChildOf
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Name = world:component()
|
||||
local Position = world:component()
|
||||
local Star = world:component()
|
||||
local Planet = world:component()
|
||||
local Moon = world:component()
|
||||
|
||||
local Vector3
|
||||
do
|
||||
Vector3 = {}
|
||||
Vector3.__index = Vector3
|
||||
|
||||
function Vector3.new(x, y, z)
|
||||
x = x or 0
|
||||
y = y or 0
|
||||
z = z or 0
|
||||
return setmetatable({ X = x, Y = y, Z = z }, Vector3)
|
||||
end
|
||||
|
||||
function Vector3.__add(left, right)
|
||||
return Vector3.new(left.X + right.X, left.Y + right.Y, left.Z + right.Z)
|
||||
end
|
||||
|
||||
function Vector3.__mul(left, right)
|
||||
if typeof(right) == "number" then
|
||||
return Vector3.new(left.X * right, left.Y * right, left.Z * right)
|
||||
end
|
||||
return Vector3.new(left.X * right.X, left.Y * right.Y, left.Z * right.Z)
|
||||
end
|
||||
|
||||
Vector3.one = Vector3.new(1, 1, 1)
|
||||
Vector3.zero = Vector3.new()
|
||||
end
|
||||
|
||||
local function path(entity)
|
||||
local str = world:get(entity, Name)
|
||||
local parent
|
||||
while true do
|
||||
parent = world:parent(entity)
|
||||
if not parent then
|
||||
break
|
||||
end
|
||||
entity = parent
|
||||
str = world:get(parent, Name) .. "/" .. str
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
local function iterate(entity, parent)
|
||||
local p = world:get(entity, Position)
|
||||
local actual = p + parent
|
||||
print(path(entity))
|
||||
print(`\{{actual.X}, {actual.Y}, {actual.Z}}`)
|
||||
|
||||
for child in world:query(pair(ChildOf, entity)) do
|
||||
--print(world:get(child, Name))
|
||||
iterate(child, actual)
|
||||
end
|
||||
end
|
||||
|
||||
local sun = world:entity()
|
||||
world:add(sun, Star)
|
||||
world:set(sun, Position, Vector3.one)
|
||||
world:set(sun, Name, "Sun")
|
||||
do
|
||||
local earth = world:entity()
|
||||
world:set(earth, Name, "Earth")
|
||||
world:add(earth, pair(ChildOf, sun))
|
||||
world:add(earth, Planet)
|
||||
world:set(earth, Position, Vector3.one * 3)
|
||||
|
||||
do
|
||||
local moon = world:entity()
|
||||
world:set(moon, Name, "Moon")
|
||||
world:add(moon, pair(ChildOf, earth))
|
||||
world:add(moon, Moon)
|
||||
world:set(moon, Position, Vector3.one * 0.1)
|
||||
|
||||
print(`Child of Earth? {world:has(moon, pair(ChildOf, earth))}`)
|
||||
end
|
||||
|
||||
local venus = world:entity()
|
||||
world:set(venus, Name, "Venus")
|
||||
world:add(venus, pair(ChildOf, sun))
|
||||
world:add(venus, Planet)
|
||||
world:set(venus, Position, Vector3.one * 2)
|
||||
|
||||
local mercury = world:entity()
|
||||
world:set(mercury, Name, "Mercury")
|
||||
world:add(mercury, pair(ChildOf, sun))
|
||||
world:add(mercury, Planet)
|
||||
world:set(mercury, Position, Vector3.one)
|
||||
|
||||
iterate(sun, Vector3.zero)
|
||||
end
|
||||
|
||||
-- Output:
|
||||
-- Child of Earth? true
|
||||
-- Sun
|
||||
-- {1, 1, 1}
|
||||
-- Sun/Mercury
|
||||
-- {2, 2, 2}
|
||||
-- Sun/Venus
|
||||
-- {3, 3, 3}
|
||||
-- Sun/Earth
|
||||
-- {4, 4, 4}
|
||||
-- Sun/Earth/Moon
|
||||
-- {4.1, 4.1, 4.1}
|
|
@ -1,21 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Model = world:component()
|
||||
|
||||
-- It is important to define hooks for the component before the component is ever used
|
||||
-- otherwise the hooks will never invoke!
|
||||
world:set(Model, jecs.OnRemove, function(entity)
|
||||
-- OnRemove is invoked before the component and its value is removed
|
||||
-- which provides a stable reference to the entity at deletion.
|
||||
-- This means that it is safe to retrieve the data inside of a hook
|
||||
local model = world:get(entity, Model)
|
||||
model:Destroy()
|
||||
end)
|
||||
|
||||
world:set(Model, jecs.OnSet, function(entity, model)
|
||||
-- OnSet is invoked after the data has been assigned.
|
||||
-- It also returns the data for faster access.
|
||||
-- There may be some logic to do some side effects on reassignments
|
||||
model:SetAttribute("entityId", entity)
|
||||
end)
|
|
@ -1,63 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Position = world:component()
|
||||
local Velocity = world:component()
|
||||
local Name = world:component()
|
||||
|
||||
local Vector3
|
||||
do
|
||||
Vector3 = {}
|
||||
Vector3.__index = Vector3
|
||||
|
||||
function Vector3.new(x, y, z)
|
||||
x = x or 0
|
||||
y = y or 0
|
||||
z = z or 0
|
||||
return setmetatable({ X = x, Y = y, Z = z }, Vector3)
|
||||
end
|
||||
|
||||
function Vector3.__add(left, right)
|
||||
return Vector3.new(left.X + right.X, left.Y + right.Y, left.Z + right.Z)
|
||||
end
|
||||
|
||||
function Vector3.__mul(left, right)
|
||||
if typeof(right) == "number" then
|
||||
return Vector3.new(left.X * right, left.Y * right, left.Z * right)
|
||||
end
|
||||
return Vector3.new(left.X * right.X, left.Y * right.Y, left.Z * right.Z)
|
||||
end
|
||||
|
||||
Vector3.one = Vector3.new(1, 1, 1)
|
||||
Vector3.zero = Vector3.new()
|
||||
end
|
||||
|
||||
-- Create a few test entities for a Position, Velocity query
|
||||
local e1 = world:entity()
|
||||
world:set(e1, Name, "e1")
|
||||
world:set(e1, Position, Vector3.new(10, 20, 30))
|
||||
world:set(e1, Velocity, Vector3.new(1, 2, 3))
|
||||
|
||||
local e2 = world:entity()
|
||||
world:set(e2, Name, "e2")
|
||||
world:set(e2, Position, Vector3.new(10, 20, 30))
|
||||
world:set(e2, Velocity, Vector3.new(4, 5, 6))
|
||||
|
||||
-- This entity will not match as it does not have Position, Velocity
|
||||
local e3 = world:entity()
|
||||
world:set(e3, Name, "e3")
|
||||
world:set(e3, Position, Vector3.new(10, 20, 30))
|
||||
|
||||
-- Create an uncached query for Position, Velocity.
|
||||
for entity, p, v in world:query(Position, Velocity) do
|
||||
-- Iterate entities matching the query
|
||||
p.X += v.X
|
||||
p.Y += v.Y
|
||||
p.Z += v.Z
|
||||
|
||||
print(`{world:get(entity, Name)}: \{{p.X}, {p.Y}, {p.Z}}`)
|
||||
end
|
||||
|
||||
-- Output:
|
||||
-- e2: {14, 25, 36}
|
||||
-- e1: {11, 22, 33}
|
|
@ -1,61 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
|
||||
local world = jecs.World.new()
|
||||
local Name = world:component()
|
||||
|
||||
local function named(ctr, name)
|
||||
local e = ctr(world)
|
||||
world:set(e, Name, name)
|
||||
return e
|
||||
end
|
||||
local function name(e)
|
||||
return world:get(e, Name)
|
||||
end
|
||||
|
||||
local Position = named(world.component, "Position") :: jecs.Entity<Vector3>
|
||||
local Previous = jecs.Rest
|
||||
local PreviousPosition = jecs.pair(Previous, Position)
|
||||
|
||||
local added = world
|
||||
:query(Position)
|
||||
:without(PreviousPosition)
|
||||
:cached()
|
||||
local changed = world
|
||||
:query(Position, PreviousPosition)
|
||||
:cached()
|
||||
local removed = world
|
||||
:query(PreviousPosition)
|
||||
:without(Position)
|
||||
:cached()
|
||||
|
||||
local e1 = named(world.entity, "e1")
|
||||
world:set(e1, Position, Vector3.new(10, 20, 30))
|
||||
|
||||
local e2 = named(world.entity, "e2")
|
||||
world:set(e2, Position, Vector3.new(10, 20, 30))
|
||||
|
||||
for e, p in added:iter() do
|
||||
print(`Added {e}: \{{p.X}, {p.Y}, {p.Z}}`)
|
||||
world:set(e, PreviousPosition, p)
|
||||
end
|
||||
|
||||
world:set(e1, Position, "")
|
||||
|
||||
for e, new, old in changed:iter() do
|
||||
if new ~= old then
|
||||
print(`{name(new)}'s Position changed from \{{old.X}, {old.Y}, {old.Z}\} to \{{new.X}, {new.Y}, {new.Z}\}`)
|
||||
world:set(e, PreviousPosition, new)
|
||||
end
|
||||
end
|
||||
|
||||
world:remove(e2, Position)
|
||||
|
||||
for e in removed:iter() do
|
||||
print(`Position was removed from {name(e)}`)
|
||||
end
|
||||
|
||||
-- Output:
|
||||
-- Added 265: {10, 20, 30}
|
||||
-- Added 264: {10, 20, 30}
|
||||
-- e1's Position changed from {10, 20, 30} to {999, 999, 1998}
|
||||
-- Position was removed from e2
|
|
@ -1,125 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
local pair = jecs.pair
|
||||
local ChildOf = jecs.ChildOf
|
||||
local __ = jecs.Wildcard
|
||||
local Name = jecs.Name
|
||||
local world = jecs.World.new()
|
||||
|
||||
type Id<T = nil> = number & { __T: T }
|
||||
local Voxel = world:component() :: Id
|
||||
local Position = world:component() :: Id<Vector3>
|
||||
local Perception = world:component() :: Id<{
|
||||
range: number,
|
||||
fov: number,
|
||||
dir: Vector3,
|
||||
}>
|
||||
local PrimaryPart = world:component() :: Id<Part>
|
||||
|
||||
local local_player = game:GetService("Players").LocalPlayer
|
||||
|
||||
local function distance(a: Vector3, b: Vector3)
|
||||
return (b - a).Magnitude
|
||||
end
|
||||
|
||||
local function is_in_fov(a: Vector3, b: Vector3, forward_dir: Vector3, fov_angle: number)
|
||||
local to_target = b - a
|
||||
|
||||
local forward_xz = Vector3.new(forward_dir.X, 0, forward_dir.Z).Unit
|
||||
local to_target_xz = Vector3.new(to_target.X, 0, to_target.Z).Unit
|
||||
|
||||
local angle_to_target = math.deg(math.atan2(to_target_xz.Z, to_target_xz.X))
|
||||
local forward_angle = math.deg(math.atan2(forward_xz.Z, forward_xz.X))
|
||||
|
||||
local angle_difference = math.abs(forward_angle - angle_to_target)
|
||||
|
||||
if angle_difference > 180 then
|
||||
angle_difference = 360 - angle_difference
|
||||
end
|
||||
|
||||
return angle_difference <= (fov_angle / 2)
|
||||
end
|
||||
|
||||
local map = {}
|
||||
local grid = 50
|
||||
|
||||
local function add_to_voxel(source: number, position: Vector3, prev_voxel_id: number?)
|
||||
local hash = position // grid
|
||||
local voxel_id = map[hash]
|
||||
if not voxel_id then
|
||||
voxel_id = world:entity()
|
||||
world:add(voxel_id, Voxel)
|
||||
world:set(voxel_id, Position, hash)
|
||||
map[hash] = voxel_id
|
||||
end
|
||||
if prev_voxel_id ~= nil then
|
||||
world:remove(source, pair(ChildOf, prev_voxel_id))
|
||||
end
|
||||
world:add(source, pair(ChildOf, voxel_id))
|
||||
end
|
||||
|
||||
local function reconcile_client_owned_assembly_to_voxel(dt: number)
|
||||
for e, part, position in world:query(PrimaryPart, Position) do
|
||||
local p = part.Position
|
||||
if p ~= position then
|
||||
world:set(e, Position, p)
|
||||
local voxel_id = world:target(e, ChildOf, 0)
|
||||
if map[p // grid] == voxel_id then
|
||||
continue
|
||||
end
|
||||
|
||||
add_to_voxel(e, p, voxel_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function update_camera_direction(dt: number)
|
||||
for _, perception in world:query(Perception) do
|
||||
perception.dir = workspace.CurrentCamera.CFrame.LookVector
|
||||
end
|
||||
end
|
||||
|
||||
local function perceive_enemies(dt: number)
|
||||
local it = world:query(Perception, Position, PrimaryPart)
|
||||
-- There is only going to be one entity matching the query
|
||||
local e, self_perception, self_position, self_primary_part = it()
|
||||
|
||||
local voxel_id = map[self_primary_part.Position // grid]
|
||||
local nearby_entities_query = world:query(Position, pair(ChildOf, voxel_id))
|
||||
|
||||
for enemy, target_position in nearby_entities_query do
|
||||
if distance(self_position, target_position) > self_perception.range then
|
||||
continue
|
||||
end
|
||||
|
||||
if is_in_fov(self_position, target_position, self_perception.dir, self_perception.fov) then
|
||||
local p = target_position
|
||||
print(`Entity {world:get(e, Name)} can see target {world:get(enemy, Name)} at ({p.X}, {p.Y}, {p.Z})`)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local player = world:entity()
|
||||
world:set(player, Perception, {
|
||||
range = 100,
|
||||
fov = 90,
|
||||
dir = Vector3.new(1, 0, 0),
|
||||
})
|
||||
world:set(player, Name, "LocalPlayer")
|
||||
local primary_part = (local_player.Character :: Model).PrimaryPart :: Part
|
||||
world:set(player, PrimaryPart, primary_part)
|
||||
world:set(player, Position, Vector3.zero)
|
||||
|
||||
local enemy = world:entity()
|
||||
world:set(enemy, Name, "Enemy $1")
|
||||
world:set(enemy, Position, Vector3.new(50, 0, 20))
|
||||
|
||||
add_to_voxel(player, primary_part.Position)
|
||||
add_to_voxel(enemy, world)
|
||||
|
||||
local dt = 1 / 60
|
||||
reconcile_client_owned_assembly_to_voxel(dt)
|
||||
update_camera_direction(dt)
|
||||
perceive_enemies(dt)
|
||||
|
||||
-- Output:
|
||||
-- LocalPlayer can see target Enemy $1
|
|
@ -1,37 +0,0 @@
|
|||
local jecs = require("@jecs")
|
||||
local pair = jecs.pair
|
||||
local world = jecs.World.new()
|
||||
local Name = world:component()
|
||||
|
||||
local function named(ctr, name)
|
||||
local e = ctr(world)
|
||||
world:set(e, Name, name)
|
||||
return e
|
||||
end
|
||||
local function name(e)
|
||||
return world:get(e, Name)
|
||||
end
|
||||
|
||||
local Eats = world:component()
|
||||
local Apples = named(world.entity, "Apples")
|
||||
local Oranges = named(world.entity, "Oranges")
|
||||
|
||||
local bob = named(world.entity, "Bob")
|
||||
world:set(bob, pair(Eats, Apples), 10)
|
||||
|
||||
local alice = named(world.entity, "Alice")
|
||||
world:set(alice, pair(Eats, Oranges), 5)
|
||||
|
||||
-- Aliasing the wildcard to symbols improves readability and ease of writing
|
||||
local __ = jecs.Wildcard
|
||||
|
||||
-- Create a query that matches edible components
|
||||
for entity, amount in world:query(pair(Eats, __)) do
|
||||
-- Iterate the query
|
||||
local food = world:target(entity, Eats)
|
||||
print(`{name(entity)} eats {amount} {name(food)}`)
|
||||
end
|
||||
|
||||
-- Output:
|
||||
-- Alice eats 5 Oranges
|
||||
-- Bob eats 10 Apples
|
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 142 KiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.5 KiB |
|
@ -1,24 +0,0 @@
|
|||
declare function afterAll(callback: () -> ()): ()
|
||||
declare function afterEach(callback: () -> ()): ()
|
||||
|
||||
declare function beforeAll(callback: () -> ()): ()
|
||||
declare function beforeEach(callback: () -> ()): ()
|
||||
|
||||
declare function describe(phrase: string, callback: () -> ()): ()
|
||||
declare function describeFOCUS(phrase: string, callback: () -> ()): ()
|
||||
declare function fdescribe(phrase: string, callback: () -> ()): ()
|
||||
declare function describeSKIP(phrase: string, callback: () -> ()): ()
|
||||
declare function xdescribe(phrase: string, callback: () -> ()): ()
|
||||
|
||||
declare function expect(value: any): any
|
||||
|
||||
declare function FIXME(optionalMessage: string?): ()
|
||||
declare function FOCUS(): ()
|
||||
declare function SKIP(): ()
|
||||
|
||||
declare function it(phrase: string, callback: () -> ()): ()
|
||||
declare function itFOCUS(phrase: string, callback: () -> ()): ()
|
||||
declare function fit(phrase: string, callback: () -> ()): ()
|
||||
declare function itSKIP(phrase: string, callback: () -> ()): ()
|
||||
declare function xit(phrase: string, callback: () -> ()): ()
|
||||
declare function itFIXME(phrase: string, callback: () -> ()): ()
|
|
@ -5,7 +5,7 @@ local ansi = require("@tools/ansi")
|
|||
|
||||
local function pe(e: any)
|
||||
local gen = ECS_GENERATION(e)
|
||||
return ansi.green(`e{ECS_ID(e)}`)..ansi.yellow(`v{gen}`)
|
||||
return ansi.green(`e{ECS_ID(e)}`) .. ansi.yellow(`v{gen}`)
|
||||
end
|
||||
|
||||
local function name(world: jecs.World, id: any)
|
||||
|
|
|
@ -62,7 +62,7 @@ local function lifetime_tracker_add(world: jecs.World, opt)
|
|||
w.print_entity_index = function(self)
|
||||
local max_id = entity_index.max_id
|
||||
local alive_count = entity_index.alive_count
|
||||
local alive = table.move(dense_array, 1+jecs.Rest::any, alive_count, 1, {})
|
||||
local alive = table.move(dense_array, 1 + jecs.Rest :: any, alive_count, 1, {})
|
||||
local dead = table.move(dense_array, alive_count + 1, max_id, 1, {})
|
||||
|
||||
local sep = "|--------|"
|
||||
|
@ -98,7 +98,7 @@ local function lifetime_tracker_add(world: jecs.World, opt)
|
|||
|
||||
local max_id = entity_index.max_id
|
||||
local alive_count = entity_index.alive_count
|
||||
local alive = table.move(dense_array, 1+jecs.Rest::any, alive_count, 1, {})
|
||||
local alive = table.move(dense_array, 1 + jecs.Rest :: any, alive_count, 1, {})
|
||||
local dead = table.move(dense_array, alive_count + 1, max_id, 1, {})
|
||||
|
||||
local data = {}
|
||||
|
@ -127,7 +127,7 @@ local function lifetime_tracker_add(world: jecs.World, opt)
|
|||
local entity = dense_array[i]
|
||||
local id = ECS_ID(entity)
|
||||
-- Push entity and id into the new `entities` table
|
||||
table.insert(entities, {entity = entity, id = id})
|
||||
table.insert(entities, { entity = entity, id = id })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -169,7 +169,6 @@ local function lifetime_tracker_add(world: jecs.World, opt)
|
|||
print(`*added ({pe(relation)}, {pe(target)}) to {pe(entity)}`)
|
||||
pad()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local world_delete = world.delete
|
||||
|
@ -199,7 +198,9 @@ local function lifetime_tracker_add(world: jecs.World, opt)
|
|||
break
|
||||
else
|
||||
for _, entity in archetype.entities do
|
||||
print(`*removed dependency ({pe(jecs.pair_first(world, id))}, {pe(object)}) from {pe(entity)}`)
|
||||
print(
|
||||
`*removed dependency ({pe(jecs.pair_first(world, id))}, {pe(object)}) from {pe(entity)}`
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -534,7 +534,7 @@ return {
|
|||
FINISH = FINISH,
|
||||
SKIP = SKIP,
|
||||
FOCUS = FOCUS,
|
||||
CHECK_EXPECT_ERR = CHECK_EXPECT_ERR
|
||||
CHECK_EXPECT_ERR = CHECK_EXPECT_ERR,
|
||||
}
|
||||
end,
|
||||
|
||||
|
|