if (oldCount != count)
никогда не заходит внутрь т.к. этот код блокирует обработку кадров. Чтобы кадры продолжили обрабатываться надо в цикле использовать yield. Заодно можно заменить это ожидание циклом на корутину от юнити: yield return new WaitForSeconds(5);
Background="Transparent"
(прозрачный цвет считается за фон, но визуально ничего не меняет), то всё будет работать.public class SettingViewHost
{
public IReadOnlyCollection<SettingView>? Views { get; init; }
}
public class SettingView
{
public string? Name { get; init; }
public IReadOnlyCollection<ItemData>? Options { get; init; }
}
public class ItemData
{
public string? Name { get; init; }
public int GridRow { get; init; }
public int GridColumn { get; init; }
}
public class BooleanItemData : ItemData // TODO implement INotifyPropertyChanged and raise PropertyChanged in Value setter
{
public bool Value { get; set; }
}
public class StringItemData : ItemData // TODO implement INotifyPropertyChanged and raise PropertyChanged in Value setter
{
public string Value { get; set; } = string.Empty;
}
<DataTemplate DataType="{x:Type local:StringItemData}">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name, Mode=OneTime}" />
<TextBox Text="{Binding Value}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:BooleanItemData}">
<CheckBox Content="{Binding Name, Mode=OneTime}" IsChecked="{Binding Value}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:SettingView}">
<ItemsControl ItemsSource="{Binding Options}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid IsItemsHost="True">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Grid.Column" Value="{Binding GridColumn, Mode=OneTime}" />
<Setter Property="Grid.Row" Value="{Binding GridRow, Mode=OneTime}" />
<Setter Property="Margin" Value="4" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SettingViewHost}">
<StackPanel Orientation="Vertical">
<ComboBox Name="ComboBox" ItemsSource="{Binding Views}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:SettingView}">
<TextBlock Text="{Binding Name, Mode=OneTime}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ContentControl Content="{Binding ElementName=ComboBox, Path=SelectedItem}" />
</StackPanel>
</DataTemplate>
Collider2D
есть метод GetContacts.ContactPoint2D
.ContactPoint2D
есть поле normal - нормаль поверхности в точке коллизии. Collider2D collider;
var contacts = new List<ContactPoint2D>();
collider.GetContacts(contacts);
foreach (var contact in contacts)
{
var surfaceNormal = contact.normal;
}
IEqualityComparer<T>
используется в коде с обобщениями (generics).IEqualityComparer<T>
, то при сравнении ключей-структур постоянно бы происходил боксинг, что не очень эффективно. (У простых структур всё-равно будет боксинг, чтобы его не было надо реализовать IEquatable).IEqualityComparer<T>
мало, есть более лаконичные вариант для Equals и GetHashCode. angle = Mathf.LerpAngle(angle, angle - additionalAngle, direction.magnitude - 3);
if (direction.magnitude < 3)
targetPos = ownerPos + direction.normalized * 3;
Почему это поле не передается через, передается null
CommandParameter="{Binding ElementName=selfUserControl,Path=Points, Mode=OneWay}">, selfUserControl x:Name элемента.
Находил примеры, там везде свойство ItemsSource, но такого свойства нету у Canvas
использовать условные конструкции для решения об отображении или неотображении тех или иных элементов GUI, либо иметь разные XAML-формы для разных групп пользователей
// [][] 4865 // [,] 5192 // [] 4852
IL_0000: ldarg 1 // кладёт в стек первый аргумент
IL_0001: ldarg 2 // кладёт в стек второй аргумент
IL_0002: sub // достаёт из стека два последних значения и отнимает последний от пред последнего (т.е. будет arg.2 - arg.1), результат складывается в стек
IL_0003: brtrue.s IL_0011 // достаёт из стека значение, если оно не 0, переходит к инструкции IL_0011, если 0 исполнения идёт дальше на I_0005
IL_0005: ldstr "zero" // загружает в стек строку "zero"
IL_000a: call void System.Console::WriteLine(string) // вызывает вывод в консоль, из стека достаются N нужных значений для параметров (в данном случае 1), void функция ничего в стек не добавляет
IL_000f: br.s IL_001b // переход (jump) к IL_001b
IL_0011: ldstr "not zero" // загружает в стек строку "not zero"
IL_0016: call void System.Console::WriteLine(string) // вызывает вывод в консоль, из стека достаётся 1 значения для параметра
IL_001b: ldstr "done" // загружает в стек строку ...
IL_0020: call void System.Console::WriteLine(string) // ...
#include <stdio.h>
enum Opcode {
OP_LOAD_ARGUMENT,
OP_LOAD_STRING,
OP_SUBTRACT,
OP_GOTO,
OP_GOTO_IF_TRUE,
OP_CALL,
OP_RETURN
};
union Argument {
int value;
const void* pointer;
};
struct Instruction {
Opcode opcode;
Argument arg;
};
void run_vm(const Instruction* instructions, const Argument* args) {
Argument stack[16];
Argument* stack_pointer = &stack[0];
int address = 0;
while(true) {
const Instruction instruction = instructions[address];
address++;
switch(instruction.opcode) {
case OP_RETURN:
return;
case OP_LOAD_ARGUMENT:
*stack_pointer = args[instruction.arg.value];
stack_pointer++;
break;
case OP_LOAD_STRING:
*stack_pointer = instruction.arg;
stack_pointer++;
break;
case OP_SUBTRACT:
{
stack_pointer--;
int b = stack_pointer->value;
stack_pointer--;
int a = stack_pointer->value;
stack_pointer->value = a - b;
stack_pointer++;
break;
}
case OP_GOTO:
address = instruction.arg.value;
break;
case OP_GOTO_IF_TRUE:
stack_pointer--;
if(stack_pointer->value != 0)
address = instruction.arg.value;
break;
case OP_CALL:
void (* fn)(const void*) = (void (*)(const void*))instruction.arg.pointer;
stack_pointer--;
fn(stack_pointer->pointer);
break;
}
}
}
void print(const char* text) { printf("%s\n", text); }
int main(int argc, char** argv) {
const Instruction instructions[] = {
/* 0 */ { OP_LOAD_ARGUMENT, { 0 } },
/* 1 */ { OP_LOAD_ARGUMENT, { 1 } },
/* 2 */ { OP_SUBTRACT, {} },
/* 3 */ { OP_GOTO_IF_TRUE, { 0x7 } },
/* 4 */ { OP_LOAD_STRING, { .pointer = "zero" } },
/* 5 */ { OP_CALL, { .pointer = (void*)&print } }, // функции надо где-то регистрировать, чтобы знать сколько у них параметров и какого они типа
/* 6 */ { OP_GOTO, { 0x9 } },
/* 7 */ { OP_LOAD_STRING, { .pointer = "not zero" } },
/* 8 */ { OP_CALL, { .pointer = (void*)&print } },
/* 9 */ { OP_LOAD_STRING, { .pointer = "done" } },
/* A */ { OP_CALL, { .pointer = (void*)&print } },
/* B */ { OP_RETURN, {} }
};
const Argument args[] = {
{ 100500 },
{ 777 }
};
run_vm(instructions, args);
return 0;
}
string n2string = "sdfihsdfguhdsfo[ghdfhgdsfhghdfsgdfhghdsfg9wh328932u82hbsab zb cx9832u83232hbnibcz";
int countMinus3 = n2string.Length - 3;
{
string lastThreeSymbols = n2string.Substring(countMinus3);
Console.WriteLine($"lastThreeSymbols = {lastThreeSymbols}");
}
{
string lastThreeSymbols = string.Concat(n2string.Where((_, i) => i >= countMinus3));
Console.WriteLine($"lastThreeSymbols = {lastThreeSymbols}");
}
{
string lastThreeSymbols = n2string.Where((_, i) => i >= countMinus3).Aggregate(string.Empty, (s, c) => s + c);
Console.WriteLine($"lastThreeSymbols = {lastThreeSymbols}");
}
{
string lastThreeSymbols = n2string.Aggregate(string.Empty, (s, c) => (s.Length > 2 ? s.Substring(1) : s) + c);
Console.WriteLine($"lastThreeSymbols = {lastThreeSymbols}");
}
var someItems = _someService.GetList();
foreach (var item in someItems) // item внутри не используется, можно убрать этот foreach
{
var additionalItems = _additionItemsSerivce.GetList();
foreach (var additionalItem in additionalItems)
{
var properties = additionalItem.Properties;
foreach (var property in properties)
{
property.First = true;
property.First = true; // зачем делать одно и тоже два раза?
_additionItemsSerivce.UpdateProperies(additionalItem); // property не используется, значит можно вынести за этот foreach
}
}
}
var additionalItems = _additionItemsSerivce.GetList();
foreach (var additionalItem in additionalItems)
{
var properties = additionalItem.Properties;
foreach (var property in properties)
property.First = true;
_additionItemsSerivce.UpdateProperies(additionalItem);
}