Тот же Oculus Quest уже реально использовать для работы как замену монитору используя Virtual Desktop, разрешения вполне хватает. Можно расположить несколько виртуальных мониторов в пространстве. Не хватает пока поддержки режима pass through картинки окружения с камер чтобы видеть клавиатуру.
Но выход есть. На Quest ставятся андроид приложения, можно установить RDP клиент или Anydesk, и тогда удаленный рабочий стол будет висеть в окне в Oculus Home, а там есть поддержка pass through вместо виртуального окружения.
Есть еще пара способов снизить эффект укачивания. Подстмотрена в англоязычных сообществах, но проверены лично и помогают по-началу пока идет привыкание. Во-первых это стоять на коврике с четкими границами босиком, чтобы тактильно ощущать местоположение в пространстве. Во-вторых направить на себя вентилятор. Мозг "цепляется" занаправление тела относительно вентилятора и VR картинка меньше его "смущает".
За год игры раз-два в неделю по паре часов синдром укачивания пропал полностью. Изначально мог перемещатся только телепортами, при плавном перемещении начинал подташнивать через несколько минут. Сейчас спокойно играю с плавным перемещением, вестибулярка привыкла.
Из-за того что изображение растянуто на всё поле зрения картинка выглядит далеко не как 1280х1440 на мониторе на каждый глаз. Собственно если в упор к монитору придвинутся так чтобы изображение заняло всё поле зрения также сетку видно.
На самом деле разрешение нужно еще выше, я пробовал аналогичные китайские очки вместе с LG G3 в качестве экрана (5.5 дюймов 2560x1440), сетка всё равно достаточно сильно бросается в глаза.
Так это и есть почти ручной копипаст от которого я хотел избавится. На видео — Вы копируете 4 раза шаблон, выделяете 4 плейсхолдера, идете на другую вкладку, копируете 4 значения, идете обратно, вставляете.
Если надо скопировать 30 раз? И главное если массив значений не одна колонка, а двумерный массив?
Так речь не только о генерации html разметки. Вот еще реальный пример использования чтобы оценить объем копипастинга:
Исходник
#region "Value Formatting"
private void FormatValues()
{
try
{
DbUtils.StartTransaction();
EmdCreeksAndOtherDamsSampleRecord rec = this.GetRecord();
// format {0}
this.{0}.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.{0}, EmdCreeksAndOtherDamsSampleTable.{1});
}
catch
{
DbUtils.RollBackTransaction();
}
finally
{
DbUtils.EndTransaction();
}
}
#endregion
#region "DataBind"
// Populate the UI controls using the DataSource. To customize, override this method in EmdCreeksAndOtherDamsSampleTableControlRow.
public override void DataBind()
{
base.DataBind();
// Make sure that the DataSource is initialized.
if (this.DataSource == null)
{
return;
}
// For each field, check to see if a value is specified. If a value is specified,
// then format the value for display. If no value is specified, use the default value (formatted).
if (this.DataSource.{0}Specified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.{0}));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.{0}.Text = formattedValue;
}
else
{
this.{0}.Text = EmdCreeksAndOtherDamsSampleTable.{0}.Format(EmdCreeksAndOtherDamsSampleTable.{0}.DefaultValue);
}
if (this.{0}.Text == null ||
this.{0}.Text.Trim().Length == 0)
{
this.{0}.Text = " ";
}
}
#endregion
Выделяем оба шаблона, жмем ctrl+shift+z, получаем готовый кусок кода
#region "Value Formatting"
private void FormatValues()
{
try
{
DbUtils.StartTransaction();
EmdCreeksAndOtherDamsSampleRecord rec = this.GetRecord();
// format pH
this.pH.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.pH, EmdCreeksAndOtherDamsSampleTable.pHSign);
// format EC
this.EC.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.EC, EmdCreeksAndOtherDamsSampleTable.ECSign);
// format WaterTemp
this.WaterTemp.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.WaterTemp, EmdCreeksAndOtherDamsSampleTable.WaterTempSign);
// format TDS
this.TDS.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.TDS, EmdCreeksAndOtherDamsSampleTable.TDSSign);
// format Turbidity
this.Turbidity.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.Turbidity, EmdCreeksAndOtherDamsSampleTable.TurbiditySign);
// format TSS
this.TSS.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.TSS, EmdCreeksAndOtherDamsSampleTable.TSSSign);
// format Fluoride
this.Fluoride.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.Fluoride, EmdCreeksAndOtherDamsSampleTable.FluorideSign);
// format Chloride
this.Chloride.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.Chloride, EmdCreeksAndOtherDamsSampleTable.ChlorideSign);
// format SO4
this.SO4.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.SO4, EmdCreeksAndOtherDamsSampleTable.SO4Sign);
// format Nitrate
this.Nitrate.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.Nitrate, EmdCreeksAndOtherDamsSampleTable.NitrateSign);
// format Nitrite
this.Nitrite.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.Nitrite, EmdCreeksAndOtherDamsSampleTable.NitriteSign);
// format OilAndGrease
this.OilAndGrease.Text = CommonHelper.ComposeValue(rec, EmdCreeksAndOtherDamsSampleTable.OilAndGrease, EmdCreeksAndOtherDamsSampleTable.OilAndGreaseSign);
}
catch
{
DbUtils.RollBackTransaction();
}
finally
{
DbUtils.EndTransaction();
}
}
#endregion
#region "DataBind"
// Populate the UI controls using the DataSource. To customize, override this method in EmdCreeksAndOtherDamsSampleTableControlRow.
public override void DataBind()
{
base.DataBind();
// Make sure that the DataSource is initialized.
if (this.DataSource == null)
{
return;
}
// For each field, check to see if a value is specified. If a value is specified,
// then format the value for display. If no value is specified, use the default value (formatted).
if (this.DataSource.pHSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.pH));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.pH.Text = formattedValue;
}
else
{
this.pH.Text = EmdCreeksAndOtherDamsSampleTable.pH.Format(EmdCreeksAndOtherDamsSampleTable.pH.DefaultValue);
}
if (this.pH.Text == null ||
this.pH.Text.Trim().Length == 0)
{
this.pH.Text = " ";
}
if (this.DataSource.ECSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.EC));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.EC.Text = formattedValue;
}
else
{
this.EC.Text = EmdCreeksAndOtherDamsSampleTable.EC.Format(EmdCreeksAndOtherDamsSampleTable.EC.DefaultValue);
}
if (this.EC.Text == null ||
this.EC.Text.Trim().Length == 0)
{
this.EC.Text = " ";
}
if (this.DataSource.WaterTempSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.WaterTemp));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.WaterTemp.Text = formattedValue;
}
else
{
this.WaterTemp.Text = EmdCreeksAndOtherDamsSampleTable.WaterTemp.Format(EmdCreeksAndOtherDamsSampleTable.WaterTemp.DefaultValue);
}
if (this.WaterTemp.Text == null ||
this.WaterTemp.Text.Trim().Length == 0)
{
this.WaterTemp.Text = " ";
}
if (this.DataSource.TDSSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.TDS));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.TDS.Text = formattedValue;
}
else
{
this.TDS.Text = EmdCreeksAndOtherDamsSampleTable.TDS.Format(EmdCreeksAndOtherDamsSampleTable.TDS.DefaultValue);
}
if (this.TDS.Text == null ||
this.TDS.Text.Trim().Length == 0)
{
this.TDS.Text = " ";
}
if (this.DataSource.TurbiditySpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.Turbidity));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.Turbidity.Text = formattedValue;
}
else
{
this.Turbidity.Text = EmdCreeksAndOtherDamsSampleTable.Turbidity.Format(EmdCreeksAndOtherDamsSampleTable.Turbidity.DefaultValue);
}
if (this.Turbidity.Text == null ||
this.Turbidity.Text.Trim().Length == 0)
{
this.Turbidity.Text = " ";
}
if (this.DataSource.TSSSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.TSS));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.TSS.Text = formattedValue;
}
else
{
this.TSS.Text = EmdCreeksAndOtherDamsSampleTable.TSS.Format(EmdCreeksAndOtherDamsSampleTable.TSS.DefaultValue);
}
if (this.TSS.Text == null ||
this.TSS.Text.Trim().Length == 0)
{
this.TSS.Text = " ";
}
if (this.DataSource.FluorideSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.Fluoride));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.Fluoride.Text = formattedValue;
}
else
{
this.Fluoride.Text = EmdCreeksAndOtherDamsSampleTable.Fluoride.Format(EmdCreeksAndOtherDamsSampleTable.Fluoride.DefaultValue);
}
if (this.Fluoride.Text == null ||
this.Fluoride.Text.Trim().Length == 0)
{
this.Fluoride.Text = " ";
}
if (this.DataSource.ChlorideSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.Chloride));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.Chloride.Text = formattedValue;
}
else
{
this.Chloride.Text = EmdCreeksAndOtherDamsSampleTable.Chloride.Format(EmdCreeksAndOtherDamsSampleTable.Chloride.DefaultValue);
}
if (this.Chloride.Text == null ||
this.Chloride.Text.Trim().Length == 0)
{
this.Chloride.Text = " ";
}
if (this.DataSource.SO4Specified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.SO4));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.SO4.Text = formattedValue;
}
else
{
this.SO4.Text = EmdCreeksAndOtherDamsSampleTable.SO4.Format(EmdCreeksAndOtherDamsSampleTable.SO4.DefaultValue);
}
if (this.SO4.Text == null ||
this.SO4.Text.Trim().Length == 0)
{
this.SO4.Text = " ";
}
if (this.DataSource.NitrateSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.Nitrate));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.Nitrate.Text = formattedValue;
}
else
{
this.Nitrate.Text = EmdCreeksAndOtherDamsSampleTable.Nitrate.Format(EmdCreeksAndOtherDamsSampleTable.Nitrate.DefaultValue);
}
if (this.Nitrate.Text == null ||
this.Nitrate.Text.Trim().Length == 0)
{
this.Nitrate.Text = " ";
}
if (this.DataSource.NitriteSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.Nitrite));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.Nitrite.Text = formattedValue;
}
else
{
this.Nitrite.Text = EmdCreeksAndOtherDamsSampleTable.Nitrite.Format(EmdCreeksAndOtherDamsSampleTable.Nitrite.DefaultValue);
}
if (this.Nitrite.Text == null ||
this.Nitrite.Text.Trim().Length == 0)
{
this.Nitrite.Text = " ";
}
if (this.DataSource.OilAndGreaseSpecified)
{
string formattedValue = HttpUtility.HtmlEncode(this.DataSource.Format(EmdCreeksAndOtherDamsSampleTable.OilAndGrease));
if (formattedValue != null)
{
if (formattedValue.Length > (int)(100))
{
formattedValue = NetUtils.EncodeStringForHtmlDisplay(formattedValue.Substring(0, 100));
formattedValue = formattedValue + "...";
}
}
this.OilAndGrease.Text = formattedValue;
}
else
{
this.OilAndGrease.Text = EmdCreeksAndOtherDamsSampleTable.OilAndGrease.Format(EmdCreeksAndOtherDamsSampleTable.OilAndGrease.DefaultValue);
}
if (this.OilAndGrease.Text == null ||
this.OilAndGrease.Text.Trim().Length == 0)
{
this.OilAndGrease.Text = " ";
}
}
#endregion
Промахнулся с ответом на последний комментарий m1el
Отвечу всем сразу, мне нравится использовать в работе именно sublime text 2 и хотелось сделать свой рабочий инструмент чуточку удобнее и функциональнее.
Выше советуют использовать js, excel, zencoding, emmet… меня устраивала и реализация в mssql, но это все равно лишние прыжки между окнами. А теперь я могу используя Find in Files в Sublime Text найти все вхождения например field1 во все файлы проекта и быстро добавить код для пары десятков новых полей заменив field1 на {0} и нажав Ctrl+Shift+Z не выходя из текстового редактора. Т.е. речь не столько о написании кода с нуля, а о возможности быстрого изменения. Может несколько сумбурно описал, но это моя первая статья.
А в скором времени и всевозможные AI боты.
Уже есть утка-бот https://cs50.ai
ControlNet, вроде как, именно для того чтобы направить в нужную сторону сделали.
Было бы интересно посмотреть результат смеси этого видео с обработкой через которую GTA V прогнали пол года назад - https://isl-org.github.io/PhotorealismEnhancement/
Точно, читал вскользь и сразу начал пробовать, начало пролистал.
Блокировщик отключал, не помогло, сейчас еще раз попробовал - то же самое.
Интересная идея, полез сразу пробовать, но после регистрации sinric pro, при входе просто крутится please wait и ничего не происходит.
Беглый поиск выдал готовую утилиту под эту задачу - https://www.push2run.com
Тот же Oculus Quest уже реально использовать для работы как замену монитору используя Virtual Desktop, разрешения вполне хватает. Можно расположить несколько виртуальных мониторов в пространстве. Не хватает пока поддержки режима pass through картинки окружения с камер чтобы видеть клавиатуру.
Но выход есть. На Quest ставятся андроид приложения, можно установить RDP клиент или Anydesk, и тогда удаленный рабочий стол будет висеть в окне в Oculus Home, а там есть поддержка pass through вместо виртуального окружения.
Есть еще пара способов снизить эффект укачивания. Подстмотрена в англоязычных сообществах, но проверены лично и помогают по-началу пока идет привыкание. Во-первых это стоять на коврике с четкими границами босиком, чтобы тактильно ощущать местоположение в пространстве. Во-вторых направить на себя вентилятор. Мозг "цепляется" занаправление тела относительно вентилятора и VR картинка меньше его "смущает".
За год игры раз-два в неделю по паре часов синдром укачивания пропал полностью. Изначально мог перемещатся только телепортами, при плавном перемещении начинал подташнивать через несколько минут. Сейчас спокойно играю с плавным перемещением, вестибулярка привыкла.
В Quest постепенно добавляют AR функционал с новыми прошивками, но нехватает цветных камер.
Free Shipping
Если надо скопировать 30 раз? И главное если массив значений не одна колонка, а двумерный массив?
Сделал видео со своим вариантом:
Промахнулся с ответом на последний комментарий m1el
Выше советуют использовать js, excel, zencoding, emmet… меня устраивала и реализация в mssql, но это все равно лишние прыжки между окнами. А теперь я могу используя Find in Files в Sublime Text найти все вхождения например field1 во все файлы проекта и быстро добавить код для пары десятков новых полей заменив field1 на {0} и нажав Ctrl+Shift+Z не выходя из текстового редактора. Т.е. речь не столько о написании кода с нуля, а о возможности быстрого изменения. Может несколько сумбурно описал, но это моя первая статья.