Working on meta - got nodes fully in place again. Still need to store meta tags on struct members

This commit is contained in:
Peter Slattery 2020-02-22 18:54:28 -08:00
parent 5bdcb99357
commit 09e6d4d15b
11 changed files with 199 additions and 70 deletions

View File

@ -9,11 +9,13 @@
#include "gs_meta_typeinfo_generator.h" #include "gs_meta_typeinfo_generator.h"
internal void internal void
GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* CallNodeProcGen, gs_meta_preprocessor Meta) GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* NodeSpecificationGen, string_builder* CallNodeProcGen, gs_meta_preprocessor Meta)
{ {
// TODO(Peter): Create a FilterTypesByTag function to create a contiguous array // TODO(Peter): Create a FilterTypesByTag function to create a contiguous array
// of type_definition** // of type_definition**
WriteF(NodeSpecificationGen, "static node_specification_ NodeSpecifications[] = {\n");
WriteF(CallNodeProcGen, "void CallNodeProc(node_type Type, u8* NodeData)\n{\n"); WriteF(CallNodeProcGen, "void CallNodeProc(node_type Type, u8* NodeData)\n{\n");
WriteF(CallNodeProcGen, " switch(Type) { \n"); WriteF(CallNodeProcGen, " switch(Type) { \n");
for (u32 b = 0; b < Meta.TypeTable.TypeBucketsCount; b++) for (u32 b = 0; b < Meta.TypeTable.TypeBucketsCount; b++)
@ -35,24 +37,24 @@ GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* CallNodeP
AddEnumElement(NodeTypeGen, Decl->Identifier); AddEnumElement(NodeTypeGen, Decl->Identifier);
variable_decl* Param = Decl->Function.Parameters.GetElementAtIndex(0);
type_table_handle ParamTypeHandle = Param->TypeHandle;
type_definition* ParamType = GetTypeDefinition(ParamTypeHandle, Meta.TypeTable);
type_table_handle ReturnTypeHandle = Decl->Function.ReturnTypeHandle; type_table_handle ReturnTypeHandle = Decl->Function.ReturnTypeHandle;
type_definition* ReturnType = GetTypeDefinition(ReturnTypeHandle, Meta.TypeTable); type_definition* ReturnType = GetTypeDefinition(ReturnTypeHandle, Meta.TypeTable);
WriteF(NodeSpecificationGen, "{ NodeType_%S, {\"%S\", %d}, gsm_StructType_%S }, \n",
Decl->Identifier,
Decl->Identifier,
Decl->Identifier.Length,
ParamType->Identifier);
WriteF(CallNodeProcGen, " case NodeType_%.*s:\n", StringExpand(Decl->Identifier)); WriteF(CallNodeProcGen, " case NodeType_%.*s:\n", StringExpand(Decl->Identifier));
WriteF(CallNodeProcGen, " {\n"); WriteF(CallNodeProcGen, " {\n");
WriteF(CallNodeProcGen, " %.*s(", StringExpand(Decl->Identifier)); WriteF(CallNodeProcGen, " %.*s(", StringExpand(Decl->Identifier));
WriteF(CallNodeProcGen, "(%.*s*)NodeData", StringExpand(ParamType->Identifier));
for (u32 j = 0; j < Decl->Function.Parameters.Used; j++)
{
variable_decl* Param = Decl->Function.Parameters.GetElementAtIndex(j);
type_table_handle ParamTypeHandle = Param->TypeHandle;
type_definition* ParamType = GetTypeDefinition(ParamTypeHandle, Meta.TypeTable);
WriteF(CallNodeProcGen, "(%.*s*)NodeData", StringExpand(ParamType->Identifier));
if (j + 1 < Decl->Function.Parameters.Used)
{
WriteF(CallNodeProcGen, ", ");
}
}
WriteF(CallNodeProcGen, ");\n"); WriteF(CallNodeProcGen, ");\n");
WriteF(CallNodeProcGen, " } break;\n"); WriteF(CallNodeProcGen, " } break;\n");
} }
@ -61,6 +63,8 @@ GenerateNodeMetaInfo (gsm_code_generator* NodeTypeGen, string_builder* CallNodeP
WriteF(CallNodeProcGen, " }\n"); WriteF(CallNodeProcGen, " }\n");
WriteF(CallNodeProcGen, "}\n\n"); WriteF(CallNodeProcGen, "}\n\n");
WriteF(NodeSpecificationGen, "};\n\n");
FinishEnumGeneration(NodeTypeGen); FinishEnumGeneration(NodeTypeGen);
} }
@ -80,8 +84,9 @@ int main(int ArgCount, char* Args[])
FinishGeneratingTypes(&TypeGenerator); FinishGeneratingTypes(&TypeGenerator);
gsm_code_generator NodeTypeGen = BeginEnumGeneration("node_type", "NodeType", false, true); gsm_code_generator NodeTypeGen = BeginEnumGeneration("node_type", "NodeType", false, true);
string_builder NodeSpecificationGen = {0};
string_builder CallNodeProcGen = {0}; string_builder CallNodeProcGen = {0};
GenerateNodeMetaInfo(&NodeTypeGen, &CallNodeProcGen, Meta); GenerateNodeMetaInfo(&NodeTypeGen, &NodeSpecificationGen, &CallNodeProcGen, Meta);
string_builder PanelInfoGen = {0}; string_builder PanelInfoGen = {0};
@ -98,6 +103,7 @@ int main(int ArgCount, char* Args[])
if (NodeInfoH) if (NodeInfoH)
{ {
WriteStringBuilderToFile(*NodeTypeGen.Builder, NodeInfoH); WriteStringBuilderToFile(*NodeTypeGen.Builder, NodeInfoH);
WriteStringBuilderToFile(NodeSpecificationGen, NodeInfoH);
WriteStringBuilderToFile(CallNodeProcGen, NodeInfoH); WriteStringBuilderToFile(CallNodeProcGen, NodeInfoH);
fclose(NodeInfoH); fclose(NodeInfoH);
} }

View File

@ -12,8 +12,10 @@
// in your application // in your application
// //
typedef int gsm_s32;
typedef unsigned int gsm_u32; typedef unsigned int gsm_u32;
typedef unsigned long long int gsm_u64; typedef unsigned long long int gsm_u64;
typedef enum gsm_struct_type gsm_struct_type;
#define GSMetaTag(ident, ...) #define GSMetaTag(ident, ...)
@ -28,6 +30,9 @@ struct gsm_struct_member_type_info
char* Identifier; char* Identifier;
gsm_u32 IdentifierLength; gsm_u32 IdentifierLength;
gsm_u64 Offset; gsm_u64 Offset;
gsm_meta_tag* Tags;
gsm_u32 TagsCount;
}; };
struct gsm_struct_type_info struct gsm_struct_type_info
@ -45,6 +50,47 @@ struct gsm_struct_type_info
gsm_u32 MembersCount; gsm_u32 MembersCount;
}; };
static bool
gsm_CharArraysEqual(char* A, char* B)
{
bool Result = true;
char* AAt = A;
char* BAt = B;
while (*AAt && *BAt)
{
if (*AAt != *BAt)
{
Result = false;
break;
}
}
// NOTE(Peter): In case we get to the end of A or B, but not both.
// ie. the strings are equal up to a point, but one is longer.
if (*AAt != *BAt)
{
Result = false;
}
return Result;
}
static gsm_s32
gsm_GetMetaTagIndex(char* Tag, gsm_meta_tag* Tags, gsm_u32 TagCount)
{
gsm_s32 Result = -1;
for (gsm_u32 i = 0; i < TagCount; i++)
{
if (gsm_CharArraysEqual(Tag, Tags[i].Tag))
{
Result = (gsm_s32)i;
break;
}
}
return Result;
}
#define FOLDHAUS_META_INCLUDE_H #define FOLDHAUS_META_INCLUDE_H
#endif // FOLDHAUS_META_INCLUDE_H #endif // FOLDHAUS_META_INCLUDE_H

View File

@ -1,3 +1,3 @@
@echo off @echo off
remedybg build\debug_lumenarium.rdbg remedybg build\win32_foldhaus.rdbg

View File

@ -5,13 +5,9 @@
// //
#ifndef FOLDHAUS_APP_CPP #ifndef FOLDHAUS_APP_CPP
#include "../meta/gs_meta_include.h"
#include "foldhaus_platform.h" #include "foldhaus_platform.h"
#include "foldhaus_app.h" #include "foldhaus_app.h"
#include "./generated/gs_meta_generated_typeinfo.h"
internal v4 internal v4
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds) MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
{ {

View File

@ -5,6 +5,7 @@
// //
#ifndef FOLDHAUS_APP_H #ifndef FOLDHAUS_APP_H
#include "../meta/gs_meta_include.h"
#include "../meta/gs_meta_lexer.h" #include "../meta/gs_meta_lexer.h"
#include "../gs_libs/gs_font.h" #include "../gs_libs/gs_font.h"
@ -23,8 +24,8 @@
#include "foldhaus_node.h" #include "foldhaus_node.h"
// TODO(Peter): TEMPORARY // TODO(Peter): TEMPORARY
u32 NodeSpecificationsCount = 0; //u32 NodeSpecificationsCount = 0;
node_specification* NodeSpecifications = 0; //node_specification* NodeSpecifications = 0;
#include "assembly_parser.cpp" #include "assembly_parser.cpp"
@ -228,6 +229,8 @@ struct panel_definition
panel_render_proc* Render; panel_render_proc* Render;
input_command* InputCommands; input_command* InputCommands;
}; };
#include "./generated/gs_meta_generated_typeinfo.h"
#include "generated/foldhaus_nodes_generated.h"
#include "panels/foldhaus_panel_sculpture_view.h" #include "panels/foldhaus_panel_sculpture_view.h"
#include "panels/foldhaus_panel_profiler.h" #include "panels/foldhaus_panel_profiler.h"
@ -237,7 +240,6 @@ struct panel_definition
#include "panels/foldhaus_panel_node_graph.h" #include "panels/foldhaus_panel_node_graph.h"
#include "generated/foldhaus_panels_generated.h" #include "generated/foldhaus_panels_generated.h"
#include "generated/foldhaus_nodes_generated.h"
#include "foldhaus_interface.cpp" #include "foldhaus_interface.cpp"

View File

@ -5,6 +5,20 @@
// //
#ifndef FOLDHAUS_NODE_CPP #ifndef FOLDHAUS_NODE_CPP
internal b32
MemberIsInput(gsm_struct_member_type_info Member)
{
b32 Result = (0 <= gsm_GetMetaTagIndex("node_input", Member.Tags, Member.TagsCount));
return Result;
}
internal b32
MemberIsOutput(gsm_struct_member_type_info Member)
{
b32 Result = (0 <= gsm_GetMetaTagIndex("node_output", Member.Tags, Member.TagsCount));
return Result;
}
internal void internal void
ClearNodeWorkspaceStorage(pattern_node_workspace* Workspace) ClearNodeWorkspaceStorage(pattern_node_workspace* Workspace)
{ {

View File

@ -19,7 +19,8 @@ struct color_buffer
s32 LEDCount; s32 LEDCount;
}; };
// TODO(Peter): Generate this // TODO(Peter): Use the Meta RTTI
// :UseMetaInfo
enum struct_member_type enum struct_member_type
{ {
MemberType_Invalid, MemberType_Invalid,
@ -30,6 +31,8 @@ enum struct_member_type
MemberTypeCount, MemberTypeCount,
}; };
// TODO(Peter): Use the Meta RTTI
// :UseMetaInfo
struct node_struct_member struct node_struct_member
{ {
struct_member_type Type; struct_member_type Type;
@ -38,6 +41,7 @@ struct node_struct_member
b32 IsInput; b32 IsInput;
}; };
// :UseMetaInfo
struct node_specification struct node_specification
{ {
node_type Type; node_type Type;
@ -52,6 +56,13 @@ struct node_specification
b32 IsPattern; b32 IsPattern;
}; };
struct node_specification_
{
node_type Type;
string Identifier;
gsm_struct_type DataType;
};
struct pattern_node struct pattern_node
{ {
// TODO(Peter): Something to think about further down the line is the fact that // TODO(Peter): Something to think about further down the line is the fact that
@ -59,6 +70,8 @@ struct pattern_node
// an application, let alone across separate runs. If you recompile (hot load or not) // an application, let alone across separate runs. If you recompile (hot load or not)
// with a new specification, the indecies all get thrown off. Should we hash the spec // with a new specification, the indecies all get thrown off. Should we hash the spec
// names or something? // names or something?
// TODO(Peter): A more immediate thing to handle is that u32 should really be node_type
u32 SpecificationIndex; u32 SpecificationIndex;
}; };

View File

@ -6,6 +6,12 @@ enum node_type
NodeType_Count, NodeType_Count,
}; };
static node_specification_ NodeSpecifications[] = {
{ NodeType_RevolvingDiscs, {"RevolvingDiscs", 14}, gsm_StructType_revolving_discs_data },
{ NodeType_VerticalColorFadeProc, {"VerticalColorFadeProc", 21}, gsm_StructType_vertical_color_fade_data },
{ NodeType_SolidColorProc, {"SolidColorProc", 14}, gsm_StructType_solid_color_data },
};
void CallNodeProc(node_type Type, u8* NodeData) void CallNodeProc(node_type Type, u8* NodeData)
{ {
switch(Type) { switch(Type) {

View File

@ -1,25 +1,21 @@
enum gsm_struct_type enum gsm_struct_type
{ {
gsm_StructType_sin_wave_data, gsm_StructType_solid_color_data,
gsm_StructType_r32, gsm_StructType_v4,
gsm_StructType_multiply_patterns_data, gsm_StructType_float,
gsm_StructType_color_buffer, gsm_StructType_color_buffer,
gsm_StructType_led, gsm_StructType_led,
gsm_StructType_s32, gsm_StructType_s32,
gsm_StructType_v4,
gsm_StructType_float,
gsm_StructType_pixel, gsm_StructType_pixel,
gsm_StructType_u8, gsm_StructType_u8,
gsm_StructType_vertical_color_fade_data,
gsm_StructType_r32,
gsm_StructType_sin_wave_data,
gsm_StructType_multiply_patterns_data,
gsm_StructType_revolving_discs_data,
gsm_StructType_Count, gsm_StructType_Count,
}; };
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
{ "Period", 6, (u64)&((sin_wave_data*)0)->Period },
{ "Min", 3, (u64)&((sin_wave_data*)0)->Min },
{ "Max", 3, (u64)&((sin_wave_data*)0)->Max },
{ "Result", 6, (u64)&((sin_wave_data*)0)->Result },
{ "Accumulator", 11, (u64)&((sin_wave_data*)0)->Accumulator },
};
static gsm_struct_member_type_info StructMembers_v4[] = { static gsm_struct_member_type_info StructMembers_v4[] = {
{ "x", 1, (u64)&((v4*)0)->x }, { "x", 1, (u64)&((v4*)0)->x },
{ "y", 1, (u64)&((v4*)0)->y }, { "y", 1, (u64)&((v4*)0)->y },
@ -46,22 +42,52 @@ static gsm_struct_member_type_info StructMembers_color_buffer[] = {
{ "Colors", 6, (u64)&((color_buffer*)0)->Colors }, { "Colors", 6, (u64)&((color_buffer*)0)->Colors },
{ "LEDCount", 8, (u64)&((color_buffer*)0)->LEDCount }, { "LEDCount", 8, (u64)&((color_buffer*)0)->LEDCount },
}; };
static gsm_struct_member_type_info StructMembers_solid_color_data[] = {
{ "Color", 5, (u64)&((solid_color_data*)0)->Color },
{ "Result", 6, (u64)&((solid_color_data*)0)->Result },
};
static gsm_struct_member_type_info StructMembers_vertical_color_fade_data[] = {
{ "Color", 5, (u64)&((vertical_color_fade_data*)0)->Color },
{ "Min", 3, (u64)&((vertical_color_fade_data*)0)->Min },
{ "Max", 3, (u64)&((vertical_color_fade_data*)0)->Max },
{ "Result", 6, (u64)&((vertical_color_fade_data*)0)->Result },
};
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
{ "Period", 6, (u64)&((sin_wave_data*)0)->Period },
{ "Min", 3, (u64)&((sin_wave_data*)0)->Min },
{ "Max", 3, (u64)&((sin_wave_data*)0)->Max },
{ "Result", 6, (u64)&((sin_wave_data*)0)->Result },
{ "Accumulator", 11, (u64)&((sin_wave_data*)0)->Accumulator },
};
static gsm_struct_member_type_info StructMembers_multiply_patterns_data[] = { static gsm_struct_member_type_info StructMembers_multiply_patterns_data[] = {
{ "A", 1, (u64)&((multiply_patterns_data*)0)->A }, { "A", 1, (u64)&((multiply_patterns_data*)0)->A },
{ "B", 1, (u64)&((multiply_patterns_data*)0)->B }, { "B", 1, (u64)&((multiply_patterns_data*)0)->B },
{ "Result", 6, (u64)&((multiply_patterns_data*)0)->Result }, { "Result", 6, (u64)&((multiply_patterns_data*)0)->Result },
}; };
static gsm_struct_member_type_info StructMembers_revolving_discs_data[] = {
{ "Rotation", 8, (u64)&((revolving_discs_data*)0)->Rotation },
{ "ThetaZ", 6, (u64)&((revolving_discs_data*)0)->ThetaZ },
{ "ThetaY", 6, (u64)&((revolving_discs_data*)0)->ThetaY },
{ "DiscWidth", 9, (u64)&((revolving_discs_data*)0)->DiscWidth },
{ "InnerRadius", 11, (u64)&((revolving_discs_data*)0)->InnerRadius },
{ "OuterRadius", 11, (u64)&((revolving_discs_data*)0)->OuterRadius },
{ "Color", 5, (u64)&((revolving_discs_data*)0)->Color },
{ "Result", 6, (u64)&((revolving_discs_data*)0)->Result },
};
static gsm_struct_type_info StructTypes[] = { static gsm_struct_type_info StructTypes[] = {
{ gsm_StructType_sin_wave_data, "sin_wave_data", 13, 20, 0, 0, StructMembers_sin_wave_data, 5 }, { gsm_StructType_solid_color_data, "solid_color_data", 16, 36, 0, 0, StructMembers_solid_color_data, 2 },
{ gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 }, { gsm_StructType_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 3 },
{ gsm_StructType_multiply_patterns_data, "multiply_patterns_data", 22, 60, 0, 0, StructMembers_multiply_patterns_data, 3 }, { gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 },
{ gsm_StructType_color_buffer, "color_buffer", 12, 20, 0, 0, StructMembers_color_buffer, 3 }, { gsm_StructType_color_buffer, "color_buffer", 12, 20, 0, 0, StructMembers_color_buffer, 3 },
{ gsm_StructType_led, "led", 3, 20, 0, 0, StructMembers_led, 2 }, { gsm_StructType_led, "led", 3, 20, 0, 0, StructMembers_led, 2 },
{ gsm_StructType_s32, "s32", 3, 4, 0, 0, 0, 0 }, { gsm_StructType_s32, "s32", 3, 4, 0, 0, 0, 0 },
{ gsm_StructType_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 3 },
{ gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 },
{ gsm_StructType_pixel, "pixel", 5, 3, 0, 0, StructMembers_pixel, 2 }, { gsm_StructType_pixel, "pixel", 5, 3, 0, 0, StructMembers_pixel, 2 },
{ gsm_StructType_u8, "u8", 2, 1, 0, 0, 0, 0 }, { gsm_StructType_u8, "u8", 2, 1, 0, 0, 0, 0 },
{ gsm_StructType_vertical_color_fade_data, "vertical_color_fade_data", 24, 44, 0, 0, StructMembers_vertical_color_fade_data, 4 },
{ gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 },
{ gsm_StructType_sin_wave_data, "sin_wave_data", 13, 20, 0, 0, StructMembers_sin_wave_data, 5 },
{ gsm_StructType_multiply_patterns_data, "multiply_patterns_data", 22, 60, 0, 0, StructMembers_multiply_patterns_data, 3 },
{ gsm_StructType_revolving_discs_data, "revolving_discs_data", 20, 60, 0, 0, StructMembers_revolving_discs_data, 8 },
}; };
static gsm_u32 StructTypesCount = 10; static gsm_u32 StructTypesCount = 13;

View File

@ -7,7 +7,7 @@
struct visual_node struct visual_node
{ {
node_specification Spec; node_specification_ Spec;
v2 Position; v2 Position;
}; };
@ -229,19 +229,19 @@ DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer*
} }
internal void internal void
DrawNodePorts(node_specification Spec, b32 InputMask, v2 Position, r32 LineHeight, string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse) DrawNodePorts(gsm_struct_type_info NodeDataTypeInfo, b32 InputMask, v2 Position, r32 LineHeight, string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse)
{ {
rect PortBounds = rect{v2{0, 0}, v2{6, 6}}; rect PortBounds = rect{v2{0, 0}, v2{6, 6}};
v2 LinePosition = Position; v2 LinePosition = Position;
for (u32 i = 0; i < Spec.MemberListLength; i++) for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
{ {
node_struct_member Member = Spec.MemberList[i]; gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i];
if ((Member.IsInput & InputMask) > 0) if (MemberIsInput(Member))
{ {
// TODO(Peter): Can we make this rely on the same data that we use to // TODO(Peter): Can we make this rely on the same data that we use to
// render the actual connection points? // render the actual connection points?
string MemberName = MakeString(Member.Name, CharArrayLength(Member.Name)); string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign); DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign);
LinePosition.y -= LineHeight; LinePosition.y -= LineHeight;
} }
@ -249,15 +249,17 @@ DrawNodePorts(node_specification Spec, b32 InputMask, v2 Position, r32 LineHeigh
} }
internal void internal void
DrawNode (v2 Position, node_specification NodeSpecification, gs_list_handle NodeHandle, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse, memory_arena* Scratch) DrawNode (v2 Position, node_specification_ NodeSpecification, gs_list_handle NodeHandle, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse, memory_arena* Scratch)
{ {
gsm_struct_type_info NodeDataTypeInfo = StructTypes[NodeSpecification.DataType];
u32 InputMembers = 0; u32 InputMembers = 0;
u32 OutputMembers = 0; u32 OutputMembers = 0;
for (u32 i = 0; i < NodeSpecification.MemberListLength; i++) for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
{ {
node_struct_member Member = NodeSpecification.MemberList[i]; gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i];
if ((Member.IsInput & IsOutputMember) > 0) { OutputMembers++; } if (MemberIsInput(Member)) { InputMembers++; }
if ((Member.IsInput & IsInputMember) > 0) { InputMembers++; } if (MemberIsOutput(Member)) { OutputMembers++; }
} }
u32 LineCount = 1 + GSMax(InputMembers, OutputMembers); u32 LineCount = 1 + GSMax(InputMembers, OutputMembers);
@ -277,17 +279,32 @@ DrawNode (v2 Position, node_specification NodeSpecification, gs_list_handle Node
PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f}); PushRenderQuad2D(RenderBuffer, LinePosition, LinePosition + v2{NodeWidth, LineHeight}, v4{1.f, .24f, .39f, 1.f});
string NodeName = MakeString(NodeSpecification.Name, NodeSpecification.NameLength);
string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256); string NodePrintName = MakeString(PushArray(Scratch, char, 256), 0, 256);
PrintF(&NodePrintName, "%S [%d]", NodeName, NodeHandle.Index); PrintF(&NodePrintName, "%S [%d]", NodeSpecification.Identifier, NodeHandle.Index);
DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4); DrawString(RenderBuffer, NodePrintName, Interface.Font, LinePosition + TextOffset, WhiteV4);
LinePosition.y -= LineHeight; LinePosition.y -= LineHeight;
DrawNodePorts(NodeSpecification, IsInputMember, LinePosition, LineHeight, Align_Left, TextOffset, Interface, RenderBuffer, Mouse); v2 InputLinePosition = LinePosition;
v2 OutputLinePosition = v2{LinePosition.x + NodeDim.x, LinePosition.y }; v2 OutputLinePosition = v2{LinePosition.x + NodeDim.x, LinePosition.y };
v2 OutputTextOffset = v2{-TextOffset.x, TextOffset.y}; v2 OutputTextOffset = v2{-TextOffset.x, TextOffset.y};
DrawNodePorts(NodeSpecification, IsOutputMember, OutputLinePosition, LineHeight, Align_Right, OutputTextOffset, Interface, RenderBuffer, Mouse); for (u32 i = 0; i < NodeDataTypeInfo.MembersCount; i++)
{
gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[i];
string MemberName = MakeString(Member.Identifier, Member.IdentifierLength);
// TODO(Peter): Can we make this rely on the same data that we use to
// render the actual connection points?
if (MemberIsInput(Member))
{
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, Align_Left);
InputLinePosition.y -= LineHeight;
}
else if (MemberIsOutput(Member))
{
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, Align_Right);
OutputLinePosition.y -= LineHeight;
}
}
} }
internal s32 internal s32
@ -319,8 +336,10 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
pattern_node Node = *Workspace.Nodes.GetElementWithHandle(NodeHandle); pattern_node Node = *Workspace.Nodes.GetElementWithHandle(NodeHandle);
u32 SpecIndex = Node.SpecificationIndex; u32 SpecIndex = Node.SpecificationIndex;
node_specification Spec = NodeSpecifications[SpecIndex];
Result.VisualPortsCount += Spec.MemberListLength; node_specification_ Spec = NodeSpecifications[SpecIndex];
gsm_struct_type_info NodeDataTypeInfo = StructTypes[Spec.DataType];
Result.VisualPortsCount += NodeDataTypeInfo.MembersCount;;
} }
// Place nodes and connections // Place nodes and connections
@ -336,7 +355,9 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
pattern_node Node = *Workspace.Nodes.GetElementWithHandle(NodeHandle); pattern_node Node = *Workspace.Nodes.GetElementWithHandle(NodeHandle);
u32 SpecIndex = Node.SpecificationIndex; u32 SpecIndex = Node.SpecificationIndex;
node_specification Spec = NodeSpecifications[SpecIndex];
node_specification_ Spec = NodeSpecifications[SpecIndex];
gsm_struct_type_info NodeDataTypeInfo = StructTypes[Spec.DataType];
visual_node* VisualNode = Result.VisualNodes + n; visual_node* VisualNode = Result.VisualNodes + n;
VisualNode->Spec = Spec; VisualNode->Spec = Spec;
@ -345,19 +366,19 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance,
// NOTE(Peter): These start at 2 to account for the offset past the node title // NOTE(Peter): These start at 2 to account for the offset past the node title
s32 InputsCount = 2; s32 InputsCount = 2;
s32 OutputsCount = 2; s32 OutputsCount = 2;
for (u32 p = 0; p < Spec.MemberListLength; p++) for (u32 p = 0; p < NodeDataTypeInfo.MembersCount; p++)
{ {
node_struct_member Member = Spec.MemberList[p]; gsm_struct_member_type_info Member = NodeDataTypeInfo.Members[p];
rect PortBounds = {0}; rect PortBounds = {0};
v2 PortDim = v2{8, 8}; v2 PortDim = v2{8, 8};
PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2}; PortBounds.Min = VisualNode->Position + v2{0, PortDim.y / 2};
if ((Member.IsInput & IsInputMember) > 0) if (MemberIsInput(Member))
{ {
PortBounds.Min.y -= LineHeight * InputsCount++; PortBounds.Min.y -= LineHeight * InputsCount++;
PortBounds.Min.x -= PortDim.x; PortBounds.Min.x -= PortDim.x;
} }
else if ((Member.IsInput & IsOutputMember) > 0) else if (MemberIsOutput(Member))
{ {
PortBounds.Min.y -= LineHeight * OutputsCount++; PortBounds.Min.y -= LineHeight * OutputsCount++;
PortBounds.Min.x += NodeWidth; PortBounds.Min.x += NodeWidth;
@ -496,11 +517,10 @@ NodeGraph_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
string TitleString = MakeStringLiteral("Available Nodes"); string TitleString = MakeStringLiteral("Available Nodes");
DrawListElement(TitleString, &List, Mouse, RenderBuffer, State->Interface); DrawListElement(TitleString, &List, Mouse, RenderBuffer, State->Interface);
for (u32 i = 0; i < NodeSpecificationsCount; i++) for (u32 i = 0; i < NodeType_Count; i++)
{ {
node_specification Spec = NodeSpecifications[i]; node_specification_ Spec = NodeSpecifications[i];
string NodeName = MakeString(Spec.Name, Spec.NameLength); rect ElementBounds = DrawListElement(Spec.Identifier, &List, Mouse, RenderBuffer, State->Interface);
rect ElementBounds = DrawListElement(NodeName, &List, Mouse, RenderBuffer, State->Interface);
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
&& PointIsInRect(Mouse.DownPos, ElementBounds)) && PointIsInRect(Mouse.DownPos, ElementBounds))

View File

@ -5,7 +5,7 @@
// //
#ifndef TEST_PATTERNS_H #ifndef TEST_PATTERNS_H
GSMetaTag(node_struct) GSMetaTag(node_struct);
struct solid_color_data struct solid_color_data
{ {
GSMetaTag(node_input); GSMetaTag(node_input);
@ -34,7 +34,7 @@ void SolidColorProc(solid_color_data* Data)
} }
} }
GSMetaTag(node_struct) GSMetaTag(node_struct);
struct vertical_color_fade_data struct vertical_color_fade_data
{ {
GSMetaTag(node_input); GSMetaTag(node_input);
@ -75,7 +75,7 @@ void VerticalColorFadeProc(vertical_color_fade_data* Data)
} }
// Original -> DiscPatterns.pde : Revolving Discs // Original -> DiscPatterns.pde : Revolving Discs
GSMetaTag(node_struct) GSMetaTag(node_struct);
struct revolving_discs_data struct revolving_discs_data
{ {
GSMetaTag(node_input); GSMetaTag(node_input);