Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
f791b36
Small config changes to build without STL and Unreal
willvale Nov 7, 2025
8645d01
Fix optional::emplace(), which wasn't marking the newly-constructed
willvale Nov 8, 2025
00509f5
Verify sized types
willvale Nov 10, 2025
5ee26cd
Merge branch 'JBenda:master' into master
willvale Nov 10, 2025
65fdeba
Merge pull request #1 from willvale/master
willvale Nov 14, 2025
fce4b1e
Structural optimisations
willvale Nov 15, 2025
9359507
Closer to working, added original jump back for comparisons.
willvale Nov 15, 2025
45471cf
Optimise/fix jump to visit all nested knots when we change path.
willvale Nov 16, 2025
7ce4729
Use ~0 to delimit containers.
willvale Nov 17, 2025
461a652
Use explicit types in compiled data
willvale Nov 17, 2025
2f2c308
Write container data during compilation.
willvale Nov 18, 2025
7baa748
Move read_list_flag out of header and make header private to story.
willvale Nov 18, 2025
6a44a0a
Allow manual workflow dispatch.
willvale Nov 19, 2025
3958835
Allow manual dispatch of build workflow.
willvale Nov 19, 2025
b4f47e0
Fix traits for ubuntu?
willvale Nov 19, 2025
4c56a70
Fix definitions for line_type-based APIs.
willvale Nov 19, 2025
23ffa04
For real this time
willvale Nov 19, 2025
b2ea4e1
Merge branch 'master' into optimisation
willvale Nov 19, 2025
30e05b6
Fix warning - store command flags as integral.
willvale Nov 19, 2025
4d926c6
Remove profiling code.
willvale Nov 19, 2025
4f33a1e
Fix non-deref of empty container.
willvale Nov 19, 2025
3bf0ca0
inkcpp_test fixes
willvale Nov 20, 2025
eb68bad
Fix remaining unit test
willvale Nov 20, 2025
afe3e1e
Fix UTF-8 test
willvale Nov 21, 2025
88dc8d0
Rework jump slightly and fix tests.
willvale Nov 21, 2025
5f3a179
Fix restrictive numeric casts/assignments.
willvale Nov 21, 2025
adefe3e
Clangformat fixes.
willvale Nov 21, 2025
97e7f4b
Merge branch 'JBenda:master' into master
willvale Nov 21, 2025
48bac0f
Fix knot visit counts
willvale Nov 21, 2025
01a04c2
Merge branch 'fix-casts' into optimisation
willvale Nov 22, 2025
3f7f6f2
build(Options) Add NO_EH and NO_RTTI as cmake options.
JBenda Nov 28, 2025
7106179
Fix a variety of cast problems
willvale Dec 14, 2025
c180251
Merge branch 'JBenda:master' into fix-casts
willvale Dec 14, 2025
be2b6f7
Clangformat fixes
willvale Dec 14, 2025
918ebc3
Merge latest from fix_casts (and implicitly upstream)
willvale Dec 14, 2025
75c247a
Merge branch 'master' of https://github.com/willvale/inkcpp
willvale Dec 18, 2025
c540ff7
Merge branch 'JBenda:master' into master
willvale Dec 19, 2025
ecb7077
Merge branch 'master' into optimisation
willvale Dec 20, 2025
e1ca8ba
Emit list metadata in separate section and remove duplicate parsing.
willvale Dec 21, 2025
9d653ae
Don't keep trying to terminate a stream which failed.
willvale Dec 23, 2025
31885d4
Run Clangformat on affected files.
willvale Dec 23, 2025
46569c3
Missed one.
willvale Dec 23, 2025
f496cce
Merge branch 'master' into feature/#138-BinarySearch
JBenda Apr 15, 2026
cafb06c
fix(runtime): fix binary search, snapshot migration, and instruction …
JBenda May 7, 2026
a8a7ae2
fix(runtime): fix binary format, snapshot/migration correctness after…
JBenda May 8, 2026
a9a107a
build(PrReport): write ink-proof result as a seperate workflow to cir…
JBenda May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,45 +313,6 @@ jobs:
echo or upstream/master depending on your setup
fi

reporting:
name: "Pull Request Report"
# if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'brwarner/inkcpp' }}
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'master' }}
runs-on: ubuntu-latest
needs: [compilation, clang-format]
permissions:
pull-requests: write
steps:
# Download Ink Proof Results
- uses: actions/download-artifact@v4
with:
pattern: result-*
path: "results"
merge-multiple: true

# Create comment text
- name: Create Comment Text File
shell: bash
run: |
echo "### Ink Proof Results" >> comment.txt
echo "" >> comment.txt
echo "These results are obtained by running the [Ink-Proof Testing Suite](https://github.com/chromy/ink-proof) on the compiled binaries in this pull request." >> comment.txt
echo "" >> comment.txt
echo "| System | Results |" >> comment.txt
echo "| --- | --- |" >> comment.txt
FILES="results/*.txt"
for f in $FILES
do
echo "Reading results from $f"
cat "$f" >> comment.txt
done

# Post Comment
- uses: marocchino/sticky-pull-request-comment@v2.9.0
with:
recreate: true
path: comment.txt

pages:
permissions:
contents: write
Expand Down
69 changes: 69 additions & 0 deletions .github/workflows/pr-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: PR Report
on:
workflow_run:
workflows: ["build"]
types: [completed]

jobs:
reporting:
name: "Pull Request Report"
# Only run for pull requests targeting master (not push/dispatch runs)
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_branch != 'master'
runs-on: ubuntu-latest
permissions:
pull-requests: write
actions: read

steps:
# Download Ink Proof Results from the triggering workflow run
- uses: actions/download-artifact@v4
with:
pattern: result-*
path: "results"
merge-multiple: true
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

# Retrieve the PR number from the workflow run
- name: Get PR number
id: get-pr
uses: actions/github-script@v7
with:
script: |
const prs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${context.payload.workflow_run.head_repository.owner.login}:${context.payload.workflow_run.head_branch}`
});
if (prs.data.length === 0) {
core.setFailed('No matching open PR found');
return;
}
core.setOutput('pr_number', prs.data[0].number);

# Create comment text
- name: Create Comment Text File
shell: bash
run: |
echo "### Ink Proof Results" >> comment.txt
echo "" >> comment.txt
echo "These results are obtained by running the [Ink-Proof Testing Suite](https://github.com/chromy/ink-proof) on the compiled binaries in this pull request." >> comment.txt
echo "" >> comment.txt
echo "| System | Results |" >> comment.txt
echo "| --- | --- |" >> comment.txt
FILES="results/*.txt"
for f in $FILES
do
echo "Reading results from $f"
cat "$f" >> comment.txt
done

# Post Comment
- uses: marocchino/sticky-pull-request-comment@v2.9.0
with:
recreate: true
number: ${{ steps.get-pr.outputs.pr_number }}
path: comment.txt
11 changes: 5 additions & 6 deletions inkcpp/container_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ void operation<Command::READ_COUNT_VAR, value_type::divert, void>::operator()(
)
{
container_t id;
bool success
= _story.get_container_id(_story.instructions() + vals[0].get<value_type::divert>(), id);
bool success = _story.find_container_id(vals[0].get<value_type::divert>(), id);
inkAssert(success, "failed to find container to read visit count!");
stack.push(value{}.set<value_type::int32>(static_cast<int32_t>(_visit_counts.visits(id))));
}
Expand All @@ -32,14 +31,14 @@ void operation<Command::TURNS, value_type::divert, void>::operator()(
)
{
container_t id;
bool success
= _story.get_container_id(_story.instructions() + vals[0].get<value_type::divert>(), id);
bool success = _story.find_container_id(vals[0].get<value_type::divert>(), id);
inkAssert(success, "failed to find container to read turn count!");
stack.push(value{}.set<value_type::int32>(static_cast<int32_t>(_visit_counts.turns(id))));
}

void operation<
Command::CHOICE_COUNT, value_type::none, void>::operator()(basic_eval_stack& stack, value*)
void operation<Command::CHOICE_COUNT, value_type::none, void>::operator()(
basic_eval_stack& stack, value* vals
)
{
stack.push(value{}.set<value_type::int32>(static_cast<int32_t>(_runner.num_choices())));
}
Expand Down
21 changes: 11 additions & 10 deletions inkcpp/globals_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ globals_impl::globals_impl(const story_impl* story)
, _visit_counts(visit_count(), visit_count_null_value)
, _owner(story)
, _runners_start(nullptr)
, _lists(story->list_meta(), story->get_header())
, _lists(story->list_meta())
, _globals_initialized(false)
{
_visit_counts.resize(_num_containers);
Expand Down Expand Up @@ -50,12 +50,9 @@ void globals_impl::init_static_list_flags()
}
}

void globals_impl::visit(uint32_t container_id, bool entering_at_start)
void globals_impl::visit(uint32_t container_id)
{
if ((! (_owner->container_flag(container_id) & CommandFlag::CONTAINER_MARKER_ONLY_FIRST))
|| entering_at_start) {
_visit_counts.set(container_id, {_visit_counts[container_id].visits + 1, 0});
}
_visit_counts.set(container_id, {_visit_counts[container_id].visits + 1, 0});
}

uint32_t globals_impl::visits(uint32_t container_id) const
Expand Down Expand Up @@ -276,7 +273,7 @@ size_t globals_impl::snap(unsigned char* data, const snapper& snapper) const
ptr = snap_write(ptr, _turn_cnt, data != nullptr);
ptr += _visit_counts.snap(data ? ptr : nullptr, snapper);
for (unsigned i = 0; i < _visit_counts.capacity(); ++i) {
ptr = snap_write(ptr, _owner->container_hash(i), data != nullptr);
ptr = snap_write(ptr, _owner->container_data(i)._hash, data != nullptr);
}
ptr += _strings.snap(data ? ptr : nullptr, snapper);
ptr += _lists.snap(data ? ptr : nullptr, snapper);
Expand Down Expand Up @@ -307,7 +304,11 @@ const unsigned char* globals_impl::snap_load(const unsigned char* ptr, const loa
hash_t path;
ptr = snap_read(ptr, path);
container_t c_id;
bool found = _owner->get_container_id(_owner->find_offset_for(path), c_id);
ip_t container_ip = _owner->find_offset_for(path);
bool found = container_ip != nullptr
&& _owner->find_container_id(
static_cast<uint32_t>(container_ip - _owner->instructions()), c_id
);
if (! loader.migratable) {
inkAssert(found, "Invalid container id reference.");
inkAssert(c_id == i, "tracked containere are not allowed to move, expect we migrate");
Expand All @@ -332,8 +333,8 @@ const unsigned char* globals_impl::snap_load(const unsigned char* ptr, const loa

bool globals_impl::migrate_new_globals(globals_impl& new_globals, const char* list_metadata)
{
bool success = _variables.migrate(new_globals._variables)
&& ((! _lists) || _lists.migrate(list_metadata, _owner->get_header()));
bool success
= _variables.migrate(new_globals._variables) && ((! _lists) || _lists.migrate(list_metadata));
if (! success) {
return false;
}
Expand Down
3 changes: 1 addition & 2 deletions inkcpp/globals_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ class globals_impl final

public:
// Records a visit to a container
/// @param start_cmd iff the visit was initiatet through a MARKER_START_CONTAINER
void visit(uint32_t container_id, bool entering_at_start);
void visit(uint32_t container_id);

// Checks the number of visits to a container
uint32_t visits(uint32_t container_id) const;
Expand Down
34 changes: 13 additions & 21 deletions inkcpp/header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,24 @@
namespace ink::internal
{

header header::parse_header(const char* data)
bool header::verify() const
{
header res;
const char* ptr = data;
res.endien = *reinterpret_cast<const header::endian_types*>(ptr);
ptr += sizeof(header::endian_types);

using v_t = decltype(header::ink_version_number);
using vcpp_t = decltype(header::ink_bin_version_number);

if (res.endien == header::endian_types::same) {
res.ink_version_number = *reinterpret_cast<const v_t*>(ptr);
ptr += sizeof(v_t);
res.ink_bin_version_number = *reinterpret_cast<const vcpp_t*>(ptr);
if (endian() == endian_types::none) {
inkFail("Header magic number was wrong!");
return false;
}

} else if (res.endien == header::endian_types::differ) {
res.ink_version_number = swap_bytes(*reinterpret_cast<const v_t*>(ptr));
ptr += sizeof(v_t);
res.ink_bin_version_number = swap_bytes(*reinterpret_cast<const vcpp_t*>(ptr));
} else {
inkFail("Failed to parse endian encoding! %#04x", res.endien);
if (endian() == endian_types::differ) {
inkFail("Can't load content with different endian-ness!");
return false;
}

if (res.ink_bin_version_number != InkBinVersion) {
if (ink_bin_version_number != InkBinVersion) {
inkFail("InkCpp-version mismatch: file was compiled with different InkCpp-version!");
return false;
}
return res;

return true;
}

} // namespace ink::internal
8 changes: 4 additions & 4 deletions inkcpp/list_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void list_table::copy_lists(const data_t* src, data_t* dst)
}
}

list_table::list_table(const char* data, const ink::internal::header& header)
list_table::list_table(const char* data)
: _valid{false}
{
if (data == nullptr) {
Expand All @@ -43,7 +43,7 @@ list_table::list_table(const char* data, const ink::internal::header& header)
list_flag flag;
const char* ptr = data;
int start = 0;
while ((flag = header.read_list_flag(ptr)) != null_flag) {
while ((flag = read_list_flag(ptr)) != null_flag) {
// start of new list
if (static_cast<int16_t>(_list_end.size()) == flag.list_id) {
start = _list_end.size() == 0 ? 0 : _list_end.back();
Expand Down Expand Up @@ -1013,9 +1013,9 @@ float* cost_matrix(const MatchListValues& lh, const MatchListValues& rh, float d
return matrix;
}

bool list_table::migrate(const char* old_list_metadata, const ink::internal::header& header)
bool list_table::migrate(const char* old_list_metadata)
{
list_table old_ref_table(old_list_metadata, header);
list_table old_ref_table(old_list_metadata);
for (const auto& x : _data) {
old_ref_table._data.push() = x;
}
Expand Down
4 changes: 2 additions & 2 deletions inkcpp/list_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ class list_table : public snapshot_interface
list create_permament();
list& add_inplace(list& lh, list_flag rh);

list_table(const char* data, const ink::internal::header&);
list_table(const char* data);
// binary list metadata of currently loaded list
bool migrate(const char* old_list_metadata, const ink::internal::header& header);
bool migrate(const char* old_list_metadata);

explicit list_table()
: _entrySize{0}
Expand Down
Loading
Loading