fix(infra): gradle_run detecta android-sdk — issue 0076 #2

Open
dataforge wants to merge 538 commits from auto/0076-gradle-sdk-detect into master
4 changed files with 169 additions and 13 deletions
Showing only changes of commit e3cfab3dc7 - Show all commits
Binary file not shown.
+75
View File
@@ -257,3 +257,78 @@ const DagNodeDef* dag_find(const std::string& name) {
}
} // namespace fn::gfx
#ifdef DAG_CATALOG_TEST
#include <cassert>
#include <cstdio>
#include <set>
int main() {
using namespace fn::gfx;
const auto& cat = dag_catalog();
// 1. Catalog not empty
assert(!cat.empty());
// 2. All node names are unique
std::set<std::string> names;
for (const auto& n : cat) {
assert(names.insert(n.name).second && "duplicate node name");
}
// 3. Invariants by kind
int gen_count = 0, op_count = 0, blend_count = 0, output_count = 0;
for (const auto& n : cat) {
switch (n.kind) {
case DagKind::Gen:
assert(n.num_inputs == 0 && "Gen must have 0 inputs");
++gen_count; break;
case DagKind::Op:
assert(n.num_inputs >= 1 && "Op must have >= 1 input");
++op_count; break;
case DagKind::Blend:
assert(n.num_inputs >= 2 && "Blend must have >= 2 inputs");
++blend_count; break;
case DagKind::Output:
assert(n.num_inputs == 1 && "Output must have exactly 1 input");
++output_count; break;
}
assert(n.num_inputs >= 0 && n.num_inputs <= 4);
assert(n.body_glsl && "body_glsl must be set");
}
// 4. Exactly one Output in the catalog
assert(output_count == 1 && "catalog must declare exactly one Output node");
// 5. At least one Gen and one Op
assert(gen_count >= 1);
assert(op_count >= 1);
assert(blend_count >= 1);
// 6. dag_find works and returns nullptr for unknown names
assert(dag_find("output") != nullptr);
assert(dag_find("plasma") != nullptr);
assert(dag_find("__nonexistent__") == nullptr);
// 7. Every non-Output body emits non-empty GLSL
for (const auto& n : cat) {
if (n.kind == DagKind::Output) continue;
auto body = n.body_glsl(0);
assert(!body.empty() && "non-Output nodes must emit body");
// sanity: should contain a return statement
assert(body.find("return") != std::string::npos);
}
// 8. Control param indices stay within 0..3
for (const auto& n : cat) {
for (const auto& c : n.controls) {
for (int idx : c.param_idx) {
assert(idx >= -1 && idx < 4);
}
}
}
std::printf("dag_catalog: 8/8 asserts passed (%zu nodes)\n", cat.size());
return 0;
}
#endif
+80
View File
@@ -106,3 +106,83 @@ std::string compile_dag_to_glsl(const std::vector<DagStep>& pipeline) {
}
} // namespace fn::gfx
#ifdef DAG_COMPILE_TEST
#include <cassert>
#include <cstdio>
static bool contains(const std::string& hay, const std::string& needle) {
return hay.find(needle) != std::string::npos;
}
int main() {
using namespace fn::gfx;
// 1. Empty pipeline → seed color
{
std::vector<DagStep> p;
auto s = compile_dag_to_glsl(p);
assert(contains(s, "fragColor = vec4(0.04"));
}
// 2. Single Gen → fragColor = out_0
{
std::vector<DagStep> p;
DagStep g; g.id = "a"; g.name = "plasma";
p.push_back(g);
auto s = compile_dag_to_glsl(p);
assert(contains(s, "vec4 node_0"));
assert(contains(s, "vec4 out_0 = node_0("));
assert(contains(s, "fragColor = out_0"));
}
// 3. Gen + Op → Op uses out_0 as input a
{
std::vector<DagStep> p;
DagStep g; g.id = "a"; g.name = "plasma"; p.push_back(g);
DagStep o; o.id = "b"; o.name = "invert"; o.source_ids[0] = "a"; p.push_back(o);
auto s = compile_dag_to_glsl(p);
assert(contains(s, "out_1 = node_1(out_0, uv)"));
assert(contains(s, "fragColor = out_1"));
}
// 4. Blend with multi-source → both inputs resolved
{
std::vector<DagStep> p;
DagStep a; a.id = "a"; a.name = "plasma"; p.push_back(a);
DagStep b; b.id = "b"; b.name = "solid"; p.push_back(b);
DagStep m; m.id = "m"; m.name = "blend_mix";
m.source_ids[0] = "a"; m.source_ids[1] = "b";
p.push_back(m);
auto s = compile_dag_to_glsl(p);
assert(contains(s, "out_2 = node_2(out_0, out_1, uv)"));
}
// 5. Output node drives fragColor from its source, not from last index
{
std::vector<DagStep> p;
DagStep g1; g1.id = "g1"; g1.name = "plasma"; p.push_back(g1);
DagStep g2; g2.id = "g2"; g2.name = "solid"; p.push_back(g2);
DagStep o; o.id = "o"; o.name = "output";
o.source_ids[0] = "g1"; // connect Output to the plasma (first gen), not last
p.push_back(o);
auto s = compile_dag_to_glsl(p);
// Output must NOT emit a node_2 function
assert(!contains(s, "vec4 node_2("));
// fragColor must come from out_0 (plasma), not out_1 (solid)
assert(contains(s, "fragColor = out_0"));
}
// 6. Output with no connection → seed fallback
{
std::vector<DagStep> p;
DagStep g; g.id = "g"; g.name = "plasma"; p.push_back(g);
DagStep o; o.id = "o"; o.name = "output"; p.push_back(o); // no source
auto s = compile_dag_to_glsl(p);
assert(contains(s, "fragColor = vec4(0.04"));
}
std::printf("dag_compile: 6/6 asserts passed\n");
return 0;
}
#endif
+14 -13
View File
@@ -138,25 +138,26 @@ bool dag_node_editor(std::vector<DagStep>& pipeline) {
s_ctx = ed::CreateEditor(&cfg);
}
// Palette drop zone: accept dropped node types (from the Functions panel)
// and queue an add at the mouse canvas position (resolved after ed::Begin).
// Palette drop: detect without a capturing target (an InvisibleButton would
// steal clicks from the node editor). Observe the active drag-drop payload
// and, if the mouse is over this window and the user releases LMB, queue an
// add at that canvas position.
static std::string s_pending_add_name;
static ImVec2 s_pending_add_pos(0, 0);
static bool s_pending_add = false;
ImVec2 origin = ImGui::GetCursorScreenPos();
ImVec2 avail = ImGui::GetContentRegionAvail();
ImGui::InvisibleButton("##dag_drop_zone", avail,
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* p = ImGui::AcceptDragDropPayload("DAG_NODE_TYPE")) {
s_pending_add_name.assign(static_cast<const char*>(p->Data), static_cast<size_t>(p->DataSize));
s_pending_add_pos = ImGui::GetMousePos();
s_pending_add = true;
const bool window_hovered = ImGui::IsWindowHovered(
ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
if (window_hovered) {
if (const ImGuiPayload* p = ImGui::GetDragDropPayload()) {
if (p->IsDataType("DAG_NODE_TYPE") && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
s_pending_add_name.assign(static_cast<const char*>(p->Data),
static_cast<size_t>(p->DataSize));
s_pending_add_pos = ImGui::GetMousePos();
s_pending_add = true;
}
}
ImGui::EndDragDropTarget();
}
ImGui::SetCursorScreenPos(origin);
ed::SetCurrentEditor(s_ctx);
ed::Begin("dag_editor", ImVec2(0.0f, 0.0f));