cyclic dependency checking
This commit is contained in:
parent
b42299688d
commit
86c24dd112
@ -1,7 +1,5 @@
|
|||||||
@Layer base
|
@Layer base
|
||||||
|
|
||||||
@Dep mp3
|
|
||||||
|
|
||||||
//- Api
|
//- Api
|
||||||
@IncludeC base_core.h
|
@IncludeC base_core.h
|
||||||
@IncludeC base_intrinsics.h
|
@IncludeC base_intrinsics.h
|
||||||
|
|||||||
9
src/base/base_win32/base_win32.lay
Normal file
9
src/base/base_win32/base_win32.lay
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
@Layer base_win32
|
||||||
|
|
||||||
|
//- Api
|
||||||
|
@IncludeC base_win32_entry.h
|
||||||
|
@IncludeC base_win32_job.h
|
||||||
|
|
||||||
|
//- Impl
|
||||||
|
@IncludeC base_win32_entry.c
|
||||||
|
@IncludeC base_win32_job.c
|
||||||
7
src/gpu/gpu_dx12/gpu_dx12.lay
Normal file
7
src/gpu/gpu_dx12/gpu_dx12.lay
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@Layer gpu_dx12
|
||||||
|
|
||||||
|
//- Api
|
||||||
|
@IncludeC gpu_dx12.h
|
||||||
|
|
||||||
|
//- Impl
|
||||||
|
@IncludeC gpu_dx12.c
|
||||||
270
src/meta/meta.c
270
src/meta/meta.c
@ -230,6 +230,7 @@ Struct(L_BlobItemList)
|
|||||||
|
|
||||||
Struct(L_Blob)
|
Struct(L_Blob)
|
||||||
{
|
{
|
||||||
|
i64 id;
|
||||||
L_Blob *next;
|
L_Blob *next;
|
||||||
|
|
||||||
L_BlobItemList names;
|
L_BlobItemList names;
|
||||||
@ -243,8 +244,6 @@ Struct(L_Blob)
|
|||||||
L_BlobItemList default_windows_impls;
|
L_BlobItemList default_windows_impls;
|
||||||
|
|
||||||
L_BlobItemList errors;
|
L_BlobItemList errors;
|
||||||
|
|
||||||
L_BlobTopoColor topo_color;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(L_ParseResult)
|
Struct(L_ParseResult)
|
||||||
@ -261,15 +260,7 @@ L_BlobItem *L_PushBlobItem(Arena *arena, L_BlobItemList *list, String token_file
|
|||||||
item->s = item_string;
|
item->s = item_string;
|
||||||
item->token_file = token_file;
|
item->token_file = token_file;
|
||||||
item->token_pos = token_pos;
|
item->token_pos = token_pos;
|
||||||
if (list->last)
|
SllQueuePush(list->first, list->last, item);
|
||||||
{
|
|
||||||
list->last->next = item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list->first = item;
|
|
||||||
}
|
|
||||||
list->last = item;
|
|
||||||
++list->count;
|
++list->count;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -294,16 +285,8 @@ L_ParseResult L_ParseBlobsFromPaths(Arena *arena, StringList paths)
|
|||||||
L_TokenList tokens = L_TokensFromString(scratch.arena, data);
|
L_TokenList tokens = L_TokensFromString(scratch.arena, data);
|
||||||
L_ParseMode mode = L_ParseMode_None;
|
L_ParseMode mode = L_ParseMode_None;
|
||||||
L_Blob *blob = PushStruct(arena, L_Blob);
|
L_Blob *blob = PushStruct(arena, L_Blob);
|
||||||
if (result.last_blob)
|
SllQueuePush(result.first_blob, result.last_blob, blob);
|
||||||
{
|
blob->id = result.blobs_count++;
|
||||||
result.last_blob->next = blob;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.first_blob = blob;
|
|
||||||
}
|
|
||||||
result.last_blob = blob;
|
|
||||||
++result.blobs_count;
|
|
||||||
for (L_Token *token = tokens.first->next; !token->eof; token = token->next)
|
for (L_Token *token = tokens.first->next; !token->eof; token = token->next)
|
||||||
{
|
{
|
||||||
String s = token->s;
|
String s = token->s;
|
||||||
@ -394,7 +377,15 @@ L_ParseResult L_ParseBlobsFromPaths(Arena *arena, StringList paths)
|
|||||||
{
|
{
|
||||||
String name = blob->names.first->s;
|
String name = blob->names.first->s;
|
||||||
u64 hash = HashFnv64(Fnv64Basis, name);
|
u64 hash = HashFnv64(Fnv64Basis, name);
|
||||||
SetDictValue(arena, result.blobs_dict, hash, (u64)blob);
|
DictEntry *entry = EnsureDictEntry(arena, result.blobs_dict, hash);
|
||||||
|
if (entry->value == 0)
|
||||||
|
{
|
||||||
|
entry->value = (u64)blob;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
L_PushBlobItem(arena, &blob->errors, file, blob->names.first->token_pos, StringF(arena, "Layer '%F' already exists", FmtString(name)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (blob->names.count == 0)
|
else if (blob->names.count == 0)
|
||||||
{
|
{
|
||||||
@ -445,15 +436,7 @@ L_TopoItem *L_PushTopoItem(Arena *arena, L_TopoItemList *list, String token_file
|
|||||||
item->s = item_string;
|
item->s = item_string;
|
||||||
item->token_file = token_file;
|
item->token_file = token_file;
|
||||||
item->token_pos = token_pos;
|
item->token_pos = token_pos;
|
||||||
if (list->last)
|
SllQueuePush(list->first, list->last, item);
|
||||||
{
|
|
||||||
list->last->next = item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list->first = item;
|
|
||||||
}
|
|
||||||
list->last = item;
|
|
||||||
++list->count;
|
++list->count;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -466,95 +449,170 @@ L_Topo L_TopoFromLayerName(Arena *arena, StringList starting_layer_names, String
|
|||||||
/* Parse blobs */
|
/* Parse blobs */
|
||||||
L_ParseResult parsed = L_ParseBlobsFromPaths(scratch.arena, paths);
|
L_ParseResult parsed = L_ParseBlobsFromPaths(scratch.arena, paths);
|
||||||
|
|
||||||
/* Topological sort */
|
Struct(Node)
|
||||||
u64 sorted_count = 0;
|
|
||||||
L_Blob **sorted = PushStructsNoZero(scratch.arena, L_Blob *, parsed.blobs_count);
|
|
||||||
{
|
{
|
||||||
/* Build array from post-order DFS */
|
Node *next;
|
||||||
|
L_Blob *blob;
|
||||||
|
i32 state; /* 0 = enter, 1 = exit */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Topological sort via post-order DFS */
|
||||||
|
Node *first_stack = 0;
|
||||||
|
Node *first_post = 0;
|
||||||
|
Node *last_post = 0;
|
||||||
|
i8 *seen_blobs = PushStructs(scratch.arena, i8, parsed.blobs_count);
|
||||||
|
i8 *entered_blobs = PushStructs(scratch.arena, i8, parsed.blobs_count);
|
||||||
|
{
|
||||||
|
for (StringListNode *n = starting_layer_names.first; n; n = n->next)
|
||||||
{
|
{
|
||||||
u64 queue_count = 0;
|
String s = n->s;
|
||||||
L_Blob **queue = PushStructsNoZero(scratch.arena, L_Blob *, parsed.blobs_count);
|
L_Blob *starting_blob = (L_Blob *)DictValueFromHash(parsed.blobs_dict, HashFnv64(Fnv64Basis, s));
|
||||||
for (StringListNode *n = starting_layer_names.first; n; n = n->next)
|
if (starting_blob)
|
||||||
{
|
{
|
||||||
String s = n->s;
|
Node *n = PushStruct(scratch.arena, Node);
|
||||||
L_Blob *starting_blob = (L_Blob *)DictValueFromHash(parsed.blobs_dict, HashFnv64(Fnv64Basis, s));
|
n->blob = starting_blob;
|
||||||
if (starting_blob)
|
n->state = 0;
|
||||||
{
|
SllStackPush(first_stack, n);
|
||||||
if (starting_blob->topo_color == L_BlobTopoColor_None)
|
|
||||||
{
|
|
||||||
queue[queue_count++] = starting_blob;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
L_PushTopoItem(arena, &result.errors, Lit(""), 0, StringF(arena, "Layer not found with name '%F'", FmtString(s)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (queue_count > 0)
|
else
|
||||||
{
|
{
|
||||||
L_Blob *blob = queue[--queue_count];
|
L_PushTopoItem(arena, &result.errors, Lit(""), 0, StringF(arena, "Starting layer not found with name '%F'", FmtString(s)));
|
||||||
blob->topo_color = L_BlobTopoColor_Visiting;
|
}
|
||||||
b32 has_unvisited_deps = 0;
|
}
|
||||||
for (L_BlobItem *dep_item = blob->deps.first; dep_item; dep_item = dep_item->next)
|
while (first_stack)
|
||||||
|
{
|
||||||
|
L_Blob *blob = 0;
|
||||||
|
Node *stack_node = first_stack;
|
||||||
|
blob = stack_node->blob;
|
||||||
|
SllStackPop(first_stack);
|
||||||
|
|
||||||
|
if (stack_node->state == 0)
|
||||||
|
{ /* Enter */
|
||||||
|
if (!seen_blobs[blob->id])
|
||||||
{
|
{
|
||||||
String dep_name = dep_item->s;
|
if (entered_blobs[blob->id])
|
||||||
u64 dep_hash = HashFnv64(Fnv64Basis, dep_name);
|
{ /* Cycle detected */
|
||||||
L_Blob *dep_blob = (L_Blob *)DictValueFromHash(parsed.blobs_dict, dep_hash);
|
Node *first_cycle = 0;
|
||||||
if (dep_blob)
|
|
||||||
{
|
|
||||||
if (dep_blob->topo_color == L_BlobTopoColor_None)
|
|
||||||
{
|
{
|
||||||
has_unvisited_deps = 1;
|
i8 *cycle_blobs_seen = PushStructs(scratch.arena, i8, parsed.blobs_count);
|
||||||
dep_blob->topo_color = L_BlobTopoColor_Queued;
|
{
|
||||||
queue[queue_count++] = dep_blob;
|
Node *cycle_node = PushStruct(scratch.arena, Node);
|
||||||
|
cycle_node->blob = blob;
|
||||||
|
SllStackPush(first_cycle, cycle_node);
|
||||||
|
}
|
||||||
|
for (Node *n = first_stack; n; n = n->next)
|
||||||
|
{
|
||||||
|
if (entered_blobs[n->blob->id])
|
||||||
|
{
|
||||||
|
if (!cycle_blobs_seen[n->blob->id])
|
||||||
|
{
|
||||||
|
Node *cycle_node = PushStruct(scratch.arena, Node);
|
||||||
|
cycle_node->blob = n->blob;
|
||||||
|
SllStackPush(first_cycle, cycle_node);
|
||||||
|
cycle_blobs_seen[n->blob->id] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n->blob == blob) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (dep_blob->topo_color == L_BlobTopoColor_Visiting)
|
StringList cycle_names_list = ZI;
|
||||||
|
for (Node *cycle = first_cycle; cycle; cycle = cycle->next)
|
||||||
{
|
{
|
||||||
String a = ZI;
|
String name = ZI;
|
||||||
String b = ZI;
|
if (cycle->blob->names.count > 0) name = cycle->blob->names.first->s;
|
||||||
if (blob->names.count > 0) a = blob->names.first->s;
|
PushStringToList(scratch.arena, &cycle_names_list, name);
|
||||||
if (dep_blob->names.count > 0) b = dep_blob->names.first->s;
|
}
|
||||||
String s = StringF(arena, "Cyclic dependency detected while processing layer '%F' -> '%F'", FmtString(a), FmtString(b));
|
String cycle_names_str = StringFromStringList(scratch.arena, cycle_names_list, Lit(" -> "));
|
||||||
String file = PushString(arena, dep_item->token_file);
|
String name = ZI;
|
||||||
L_PushTopoItem(arena, &result.errors, file, dep_item->token_pos, s);
|
String token_file = ZI;
|
||||||
|
i64 token_pos = 0;
|
||||||
|
if (blob->names.count > 0)
|
||||||
|
{
|
||||||
|
name = blob->names.first->s;
|
||||||
|
token_file = PushString(arena, blob->names.first->token_file);
|
||||||
|
token_pos = blob->names.first->token_pos;
|
||||||
|
}
|
||||||
|
if (cycle_names_list.count > 1)
|
||||||
|
{
|
||||||
|
L_PushTopoItem(arena, &result.errors, token_file, token_pos, StringF(arena, "Cyclic dependency detected while processing dependencies for layer '%F' (%F)", FmtString(name), FmtString(cycle_names_str)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
L_PushTopoItem(arena, &result.errors, token_file, token_pos, StringF(arena, "Cyclic dependency detected while processing dependencies for layer '%F'", FmtString(name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String s = StringF(arena, "Layer '%F' not found", FmtString(dep_name));
|
/* Push blob impls */
|
||||||
String file = PushString(arena, dep_item->token_file);
|
#if PlatformIsWindows
|
||||||
L_PushTopoItem(arena, &result.errors, file, dep_item->token_pos, s);
|
for (L_BlobItem *impl_item = blob->default_windows_impls.first; impl_item; impl_item = impl_item->next)
|
||||||
|
{
|
||||||
|
String impl_name = impl_item->s;
|
||||||
|
u64 impl_hash = HashFnv64(Fnv64Basis, impl_name);
|
||||||
|
L_Blob *impl = (L_Blob *)DictValueFromHash(parsed.blobs_dict, impl_hash);
|
||||||
|
if (impl)
|
||||||
|
{
|
||||||
|
if (!seen_blobs[impl->id])
|
||||||
|
{
|
||||||
|
Node *n = PushStruct(scratch.arena, Node);
|
||||||
|
n->blob = impl;
|
||||||
|
n->state = 0;
|
||||||
|
SllStackPush(first_stack, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String file = PushString(arena, impl_item->token_file);
|
||||||
|
L_PushTopoItem(arena, &result.errors, file, impl_item->token_pos, StringF(arena, "Layer '%F' not found", FmtString(impl_name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Push blob exit */
|
||||||
|
{
|
||||||
|
entered_blobs[blob->id] = 1;
|
||||||
|
Node *n = PushStruct(scratch.arena, Node);
|
||||||
|
n->blob = blob;
|
||||||
|
n->state = 1;
|
||||||
|
SllStackPush(first_stack, n);
|
||||||
|
}
|
||||||
|
/* Push blob deps */
|
||||||
|
for (L_BlobItem *dep_item = blob->deps.first; dep_item; dep_item = dep_item->next)
|
||||||
|
{
|
||||||
|
String dep_name = dep_item->s;
|
||||||
|
u64 dep_hash = HashFnv64(Fnv64Basis, dep_name);
|
||||||
|
L_Blob *dep = (L_Blob *)DictValueFromHash(parsed.blobs_dict, dep_hash);
|
||||||
|
if (dep)
|
||||||
|
{
|
||||||
|
if (!seen_blobs[dep->id])
|
||||||
|
{
|
||||||
|
Node *n = PushStruct(scratch.arena, Node);
|
||||||
|
n->blob = dep;
|
||||||
|
n->state = 0;
|
||||||
|
SllStackPush(first_stack, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String file = PushString(arena, dep_item->token_file);
|
||||||
|
L_PushTopoItem(arena, &result.errors, file, dep_item->token_pos, StringF(arena, "Layer '%F' not found", FmtString(dep_name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_unvisited_deps)
|
|
||||||
{
|
|
||||||
queue[queue_count++] = blob;
|
|
||||||
blob->topo_color = L_BlobTopoColor_Queued;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sorted[sorted_count++] = blob;
|
|
||||||
blob->topo_color = L_BlobTopoColor_Finished;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
/* Reverse sorted array */
|
{ /* Exit */
|
||||||
i64 l = 0;
|
entered_blobs[blob->id] = 0;
|
||||||
i64 r = sorted_count - 1;
|
seen_blobs[blob->id] = 1;
|
||||||
while (l < r)
|
SllQueuePush(first_post, last_post, stack_node);
|
||||||
{
|
}
|
||||||
L_Blob *swp = sorted[l];
|
|
||||||
sorted[l] = sorted[r];
|
|
||||||
sorted[r] = swp;
|
|
||||||
++l;
|
|
||||||
--r;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process sorted blobs into result */
|
/* Process post blobs into result */
|
||||||
for (u64 i = 0; i < sorted_count; ++i)
|
for (Node *n = first_post; n; n = n->next)
|
||||||
{
|
{
|
||||||
L_Blob *blob = sorted[i];
|
L_Blob *blob = n->blob;
|
||||||
/* C includes */
|
/* C includes */
|
||||||
for (L_BlobItem *bitem = blob->c_includes.first; bitem; bitem = bitem->next)
|
for (L_BlobItem *bitem = blob->c_includes.first; bitem; bitem = bitem->next)
|
||||||
{
|
{
|
||||||
@ -574,7 +632,7 @@ L_Topo L_TopoFromLayerName(Arena *arena, StringList starting_layer_names, String
|
|||||||
/* Process errors of untouched blobs */
|
/* Process errors of untouched blobs */
|
||||||
for (L_Blob *blob = parsed.first_blob; blob; blob = blob->next)
|
for (L_Blob *blob = parsed.first_blob; blob; blob = blob->next)
|
||||||
{
|
{
|
||||||
if (blob->topo_color == L_BlobTopoColor_None && blob->errors.count > 0)
|
if (!seen_blobs[blob->id] && blob->errors.count > 0)
|
||||||
{
|
{
|
||||||
for (L_BlobItem *bitem = blob->errors.first; bitem; bitem = bitem->next)
|
for (L_BlobItem *bitem = blob->errors.first; bitem; bitem = bitem->next)
|
||||||
{
|
{
|
||||||
@ -613,15 +671,7 @@ Error *PushError(Arena *arena, ErrorList *list, String file, i64 pos, String s)
|
|||||||
e->s = s;
|
e->s = s;
|
||||||
e->file = file;
|
e->file = file;
|
||||||
e->pos = pos;
|
e->pos = pos;
|
||||||
if (list->last)
|
SllQueuePush(list->first, list->last, e);
|
||||||
{
|
|
||||||
list->last->next = e;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list->first = e;
|
|
||||||
}
|
|
||||||
list->last = e;
|
|
||||||
++list->count;
|
++list->count;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -258,6 +258,64 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
|
|||||||
#define NsFromSeconds(s) ((i64)((s) * 1000000000.0))
|
#define NsFromSeconds(s) ((i64)((s) * 1000000000.0))
|
||||||
#define SecondsFromNs(ns) ((f64)(ns) / 1000000000.0)
|
#define SecondsFromNs(ns) ((f64)(ns) / 1000000000.0)
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Linked list helper macros
|
||||||
|
|
||||||
|
/* Taken from the rad debugger
|
||||||
|
* https://github.com/EpicGamesExt/raddebugger/blob/be5634c44867a2e31f6a109df5e574930992df01/src/base/base_core.h#L239
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CheckNil(nil,p) ((p) == 0 || (p) == nil)
|
||||||
|
#define SetNil(nil,p) ((p) = nil)
|
||||||
|
|
||||||
|
//- Singly linked list stack (first & next pointers)
|
||||||
|
#define SllStackPush_N(f,n,next) ((n)->next=(f), (f)=(n))
|
||||||
|
#define SllStackPop_N(f,next) ((f)=(f)->next)
|
||||||
|
#define SllStackPush(f,n) SllStackPush_N(f,n,next)
|
||||||
|
#define SllStackPop(f) SllStackPop_N(f,next)
|
||||||
|
|
||||||
|
//- Singly linked list queue (first, last, & next pointers)
|
||||||
|
#define SllQueuePush_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
|
||||||
|
((f)=(l)=(n),SetNil(nil,(n)->next)):\
|
||||||
|
((l)->next=(n),(l)=(n),SetNil(nil,(n)->next)))
|
||||||
|
#define SllQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
|
||||||
|
((f)=(l)=(n),SetNil(nil,(n)->next)):\
|
||||||
|
((n)->next=(f),(f)=(n)))
|
||||||
|
#define SllQueuePop_NZ(nil,f,l,next) ((f)==(l)?\
|
||||||
|
(SetNil(nil,f),SetNil(nil,l)):\
|
||||||
|
((f)=(f)->next))
|
||||||
|
#define SllQueuePush_N(f,l,n,next) SllQueuePush_NZ(0,f,l,n,next)
|
||||||
|
#define SllQueuePushFront_N(f,l,n,next) SllQueuePushFront_NZ(0,f,l,n,next)
|
||||||
|
#define SllQueuePop_N(f,l,next) SllQueuePop_NZ(0,f,l,next)
|
||||||
|
#define SllQueuePush(f,l,n) SllQueuePush_NZ(0,f,l,n,next)
|
||||||
|
#define SllQueuePushFront(f,l,n) SllQueuePushFront_NZ(0,f,l,n,next)
|
||||||
|
#define SllQueuePop(f,l) SllQueuePop_NZ(0,f,l,next)
|
||||||
|
|
||||||
|
//- Doubly linked list (first, last, next, & prev pointers)
|
||||||
|
#define DllInsert_NPZ(nil,f,l,p,n,next,prev) (CheckNil(nil,f) ? \
|
||||||
|
((f) = (l) = (n), SetNil(nil,(n)->next), SetNil(nil,(n)->prev)) :\
|
||||||
|
CheckNil(nil,p) ? \
|
||||||
|
((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil,(n)->prev)) :\
|
||||||
|
((p)==(l)) ? \
|
||||||
|
((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) :\
|
||||||
|
(((!CheckNil(nil,p) && CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p))))
|
||||||
|
#define DllPushBack_NPZ(nil,f,l,n,next,prev) DllInsert_NPZ(nil,f,l,l,n,next,prev)
|
||||||
|
#define DllPushFront_NPZ(nil,f,l,n,next,prev) DllInsert_NPZ(nil,l,f,f,n,prev,next)
|
||||||
|
#define DllRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\
|
||||||
|
((n) == (l) ? (l) = (l)->prev : (0)),\
|
||||||
|
(CheckNil(nil,(n)->prev) ? (0) :\
|
||||||
|
((n)->prev->next = (n)->next)),\
|
||||||
|
(CheckNil(nil,(n)->next) ? (0) :\
|
||||||
|
((n)->next->prev = (n)->prev)))
|
||||||
|
#define DllInsert_NP(f,l,p,n,next,prev) DllInsert_NPZ(0,f,l,p,n,next,prev)
|
||||||
|
#define DllPushBack_NP(f,l,n,next,prev) DllPushBack_NPZ(0,f,l,n,next,prev)
|
||||||
|
#define DllPushFront_NP(f,l,n,next,prev) DllPushFront_NPZ(0,f,l,n,next,prev)
|
||||||
|
#define DllRemove_NP(f,l,n,next,prev) DllRemove_NPZ(0,f,l,n,next,prev)
|
||||||
|
#define DllInsert(f,l,p,n) DllInsert_NPZ(0,f,l,p,n,next,prev)
|
||||||
|
#define DllPushBack(f,l,n) DllPushBack_NPZ(0,f,l,n,next,prev)
|
||||||
|
#define DllPushFront(f,l,n) DllPushFront_NPZ(0,f,l,n,next,prev)
|
||||||
|
#define DllRemove(f,l,n) DllRemove_NPZ(0,f,l,n,next,prev)
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Type helper macros
|
//~ Type helper macros
|
||||||
|
|
||||||
|
|||||||
4
src/mp3/mp3_mmf/mp3_mmf.lay
Normal file
4
src/mp3/mp3_mmf/mp3_mmf.lay
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
@Layer mp3_mmf
|
||||||
|
|
||||||
|
//- Impl
|
||||||
|
@IncludeC mp3_mmf.c
|
||||||
7
src/platform/platform_win32/platform_win32.lay
Normal file
7
src/platform/platform_win32/platform_win32.lay
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@Layer platform_win32
|
||||||
|
|
||||||
|
//- Api
|
||||||
|
@IncludeC platform_win32.h
|
||||||
|
|
||||||
|
//- Impl
|
||||||
|
@IncludeC platform_win32.c
|
||||||
@ -8,9 +8,6 @@
|
|||||||
//- Api
|
//- Api
|
||||||
@IncludeC playback_core.h
|
@IncludeC playback_core.h
|
||||||
|
|
||||||
//- Impl
|
|
||||||
@IncludeC playback_core.c
|
|
||||||
|
|
||||||
//- Wasapi impl
|
//- Wasapi impl
|
||||||
@DefaultWindowsImpl playback_wasapi
|
@DefaultWindowsImpl playback_wasapi
|
||||||
|
|
||||||
|
|||||||
7
src/playback/playback_wasapi/playback_wasapi.lay
Normal file
7
src/playback/playback_wasapi/playback_wasapi.lay
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@Layer playback_wasapi
|
||||||
|
|
||||||
|
//- Api
|
||||||
|
@IncludeC playback_wasapi.h
|
||||||
|
|
||||||
|
//- Impl
|
||||||
|
@IncludeC playback_wasapi.c
|
||||||
@ -1,6 +1,5 @@
|
|||||||
@Layer pp
|
@Layer pp
|
||||||
|
|
||||||
|
|
||||||
//- Dependencies
|
//- Dependencies
|
||||||
@Dep base
|
@Dep base
|
||||||
@Dep gpu
|
@Dep gpu
|
||||||
@ -12,6 +11,7 @@
|
|||||||
@Dep mixer
|
@Dep mixer
|
||||||
@Dep bitbuff
|
@Dep bitbuff
|
||||||
@Dep rendertest
|
@Dep rendertest
|
||||||
|
@Dep playback
|
||||||
|
|
||||||
//- Api
|
//- Api
|
||||||
@IncludeC pp_sim.h
|
@IncludeC pp_sim.h
|
||||||
|
|||||||
7
src/ttf/ttf_dwrite/ttf_dwrite.lay
Normal file
7
src/ttf/ttf_dwrite/ttf_dwrite.lay
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@Layer ttf_dwrite
|
||||||
|
|
||||||
|
//- Api
|
||||||
|
@IncludeC ttf_dwrite.h
|
||||||
|
|
||||||
|
//- Impl
|
||||||
|
@IncludeC ttf_dwrite.c
|
||||||
Loading…
Reference in New Issue
Block a user