Запрос: SELECT to_date(DH.LAST_STATE_CHANGED, 'dd.mm.yy') FROM os_doc.document_header dh Ошибка: ORA-01861: литерал не соответствует формату строки
Ответ
Разный NLS_DATE_FORMAT в каждом из инструментов.
Запрос: SELECT to_date(DH.LAST_STATE_CHANGED, 'dd.mm.yy') FROM os_doc.document_header dh Ошибка: ORA-01861: литерал не соответствует формату строки
Разный NLS_DATE_FORMAT в каждом из инструментов.
Почему - физический, а - логический?! Аналогично и Вчера первый раз услышал, что b и strong хоть чем-то различаются, кроме названия.
Все. Отыскал. Синонимы они только внешне в обычном браузере. Если копнуть глубже, то обозначает жирный текст. Именно жирный текст(до тех пор, пока это не будет переопределено в CSS). обозначает выделенный текст. Выделенный не обязательно графически. В обычном браузере он выделяется жирным. Так договорились. Но это совершенно не обязательно: голосовые программы выделяют этот текст интонацией, некоторые мобильные браузеры подчеркивают. Вот и получается, что физически меняет стиль текста на жирный, а - сообщает об изменении логики отображения, не призывая использовать тот или иной стиль. ушел убивать себя об стенку
Добрый вечер!
Каким образом реализовать вывод списка статей? Приложение получает JSON ответ от сервера вида:
{"id":1,"message":"Тут статейка","rating":"0"}
{"id":2,"message":"Тут статейка 2","rating":"0"}
{"id":3,"message":"Тут статейка 3","rating":"0"}
Всего статей в базе около 500шт.
Мне нужно чтобы на страницу в приложении выводились 10 статей, при нажатии кнопки, эти 10 статей заменялись следующими 10-тью, и так далее.
Я думая для этого использовать ListView, но не совсем понимаю как заменять статьи при нажатии кнопки, ведь чтобы загрузить следующие 10 статей, приложение должно получить ответ от сервера с id следующих 10-ти статей.
Прошу помочь идеей реализации подобного. Или может каким нибудь другим способом это сделать.
P.S. Я не прошу код писать, а лишь идею реализации подобного!
Кроме текста статей обычно в json есть и названия. Их и показывают в списке. А сами тексты в другой Activity. ListView уже немного устарел. Вместо него сейчас используют RecyclerView. Следующая партия материалов обычно загружается, когда последний из имеющихся элементов списка появляется в области видимости. Новые элементы при этом не заменяют старые, а добавляются в конец списка.
int* a = new int[4];
++a;
--a;
delete [] a;
Будет валидным такой код?
А вот такой:
int* a = new int[4];
++a;
delete [] a;
Необходимо просто что бы какой нибудь указатель указывал на начало динамического выделенного массива? И как распознается длинна массива которую нужно уничтожить?
Может быть по типу? Но указатель указывает только на первый элемент в массиве, int*, а не ( * a)[4]. И как можно привести во втором коде int* к (*a)[4]? Почему нет неявного приведения?
Данный фрагмент кода совершенно корректный, так как оператор delete использует значение, хранящееся в указателе, которое равно значению, ранее полученному с использованием оператора new.
int* a = new int[4];
++a;
--a;
delete [] a;
Для оператора совершенно неважно, какое до этого в указателе было значение, и как оно изменялось. Чтобы это сделать еще более наглядным то вы можете написать, например,
int x;
int *px = &x;
int* a = new int[4];
px = a;
a = &x;
delete [] px;
Однако данный фрагмент кода
int* a = new int[4];
++a;
delete [] a;
некорректный, так как указатель a не содержит адрес выделенной динамически памяти. delete и free должны применятся к значению указателя полученому по new или malloc: это требование стандарта.
Обычно "под капотом" оператора new делается следующее. К запрашиваемому размеру памяти, который вы хотите выделить, добавляется к началу блока префикс, который будет хранить этот размер блока памяти. И адрес этого префикса просто вычисляется как смещение на размер слова (обычно sizeof( int) ) от начала участка памяти, адрес которой возвращается пользователю оператора new. Это значение используется, чтобы при удалении памяти правильно оценить ее размер.
Что касается вашего второго вопроса, то вы можете написать, например,
int* a = new int[4];
int ( *p )[4] = reinterpret_cast
Имеются следующие вопросы: 1. Можно ли как-то ограничить установку на, например, телефоны с API ниже 15? Вопрос заключается не в том, чтобы запретить вывод в поиске по Маркету, а именно запрет на установку. То есть, имея установочный файл, user не сможет установить его из-за низкой версии. 2. Можно ли ограничить установку по разрешению экрана? Например, пользователям с mdpi и ldpi запретить установку уже имеющегося apk-файла?
Да, можно.
Для ограничения по уровню API в манифесте есть тег uses-sdk с атрибутом android:minSdkVersion (документация)
Хочу выучить Android и, как описано тут, мне, во-первых, надо знать JAVA. Я не против JAVA и понимаю что этот язык стоит на вершине как C# , C++ и т.д. Но особо хочу написать 2D-игру (типа этой) на Андроид Скачал Андроид Студио но, как понимаю, с ним создать игру не так уж легко, как программу. Жду советы професионалов в этой сфере: 1. Какие библиотеки и 2D движки мне надо знать? 2. Какие языки предпочетаемы для Андроид кроме JAVA
Для создания игр у вас 2 пути:
1 - Использовать какой-то игровой движок/framework.
2 - Изучать openGL.
Идею о том чтобы пытаться рисовать объекты используя canvas.drawBitmap() отбрасывайте сразу - потому что это тупиковый путь на который просто можно убить время и не получить достойного результата.
Путь 1 Движки.
Одни из самых популярных - Unity - по нему куча уроков + сообщество + бесплатные и платные плагины ассеты. Минусы - немного громоздкий, но бесспорно мощный и лидирующий в отрасли.
Если хочется больше классического программирования и небольших приложений, я бы советовал обратить внимание на framework/движок libgdx, подключается к проекту элементарно, весит мало, большое сообщество, много уроков, легко начать делать простенькие спрайтовые игрушки.
вот уроки по быстрому старту от Survitruf (кстати сам Survitruf сейчас пересел на Unity).
http://suvitruf.ru/libgdx/
Обзорно по другим движкам можно посмотреть тут:
http://4pda.ru/forum/index.php?showtopic=315915
Путь 2. Изучать openGL самому не сказать чтоб очень легкий путь. Во первых сложно найти рускоязычный материал, а если и находится, то он очень устаревший годов 2005,2006 и так сейчас уже никто не делает работает.
Можно попробовать с уроков usnavii на 4pda они актуальны, есть примеры спрайтовой анимации, работы с текстурными атласами, системами частиц.
http://4pda.ru/forum/index.php?showtopic=418429
Путь долгий, сложный, но если происходит просветление и понимание что к чему, вы становитесь независимы от движков, можете легко делать простые 2d и 3d игры не загромождая их ненужными возможностями движков, делать более легкие и более быстрые приложения.
Как скопировать файл/папку на разделе ntfs в архив с сохранением всех атрибутов?
При условии, что раздел смонтирован из-под linux. Аналог tar -cvf --same-permissions
С разделами проблем нет - нужно копировать именно отдельные папки и файлы.
Это невозможно, так как драйвер NTFS под Linux не поддерживает виндовозные ACL.
IDEA сгенерировала код, мог бы кто-то построчно его прокомментировать. Не понимаю, как он работает.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair pair = (Pair) o;
if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
return !(second != null ? !second.equals(pair.second) : pair.second != null);
}
@Override
public boolean equals(Object o) {
//Если объект, с которым происходит сравнение, этим же объектом и является, то они равны. Сравнивает ссылки текущего объекта и принятого как аргумент.
if (this == o) return true;
//Если принятый объект null или другого класса, то возвращает false, не равны. При o == null они не равны, т.к. у null не может быть метода equals. Следовательно основной объект не null.
if (o == null || getClass() != o.getClass()) return false;
//кастует 'o' в Pair pair, чтобы иметь доступ к методам.
Pair pair = (Pair) o;
//Проверяет что свойство first текущего объекта не равен null. Если не равен, то сравнивает first текущего объекта, с pair.first. В случае, если они не равны, то ! инвертирует в true и условие if выполняется. Выполнится return false. Объекты не равны.
//Если first равен null, то проверяет pair.first. Если pair.first не равен null, то объекты не равны, возвращает false.
if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
//Проверяет, что second не равен null.
//Если не равен, то сравнивает second с pair.second.
//Если second == pair.second, то сначала первый ! в "!second.equals(pair.second)" инвертирует его в его в false, а второй !, который идет сразу после return, инвертирует в true. Значит вернет true, объекты равны.
//Если second == null, то проверяет второе условие. Если pair.second != null, то вернет true, который инвертируется в false.
return !(second != null ? !second.equals(pair.second) : pair.second != null);
}
В общем, почитайте про тернарный оператор ?:. Это короткий вариант if-else.
Обновление
В Java все, кроме примитивов (int, char и т.п.), является объектом и наследуется от класса Object, т. е. объект любого класса можно привести к Object, будь то String, ArrayList, Integer или MyClass. На предыдущей строке идет проверка, что оба сравниваемых объекта принадлежат 1 классу getClass() != o.getClass(). Если программа проходит эту строку, значит они одного класса, соответственно имеют одинаковые свойства и методы. Для того, чтобы привести объект класса Object к другому классу, используется кастование(cast). String str = (String) object; Читайте про наследование.
На данный вопрос уже ответили:
Git откатить rebase
1 ответ
Предиcтория фейла:
В origin master было 10 нормальных коммитов. Понадобилось 3 коммита извлечь из истории, а потом перенести в отдельный баранч
Вот мои действия
git checkout master
git branch test
git rebase -i HEAD~10 //удалил 3,9 и 10 коммит (условно hash: aaaaa,bbbbb,ccccc)
git push -f origin master
git checkout test
git rebase -i HEAD~10 //удалил 4,5,6,7,8 тоесть промежуточные
В это время мастер пошел вперед. Решив что пора вылить ветку test в origin, но что бы потом сливать ветку было проще решил подлить в нее мастер но ребейсом
git checkout test
git pull --rebase origin master
Расчитывал что мои три коммита просто перетянуться вверх истории, так как предок-коммит был. Но после кучу странных конфликтов в истории отсуствует один коммит (aaaa)
Два вопроса
В чем я ошибся и почему все так сломалось?
Что делать, как востановить утерянный коммит?
Ответ для второго пункта: все просто git reflog, находим состояние проекта до пула (например 3 шага назад) и делаем git reset --hard HEAD@{3}. Можно так же и бранч временный создать, чтобы поразбираться.
Например, имеется большой массив данных >100 переменных. А мне необходимо отобрать лишь количественные. Как можно сделать подобное?
Предварительно стоит изучить структуру данных с помощью функции str()
Выполнить поставленную Вами задачу можно следующим образом:
sapply(DF, is) # классы столбцов
DF[, sapply(DF, is.numeric)] # все столбцы класса numeric
DF[, sapply(DF, is.factor)] # все столбцы класса factor
DF[, sapply(DF, is.character)] # все столбцы класса character
Можно также использовать комбинацию sapply + which: DF[, which(sapply(DF, is.numeric))]. В некоторых случаях данный вариант показывает более высокую производительность.
Также стоит отметить, что для числовых переменных могут применяться разные классы: integer (целые числа), double (числа с плавающей запятой) или numeric (включает в себя два предыдущих типа). Это может пригодиться, если, например, необходимо отфильтровать только столбцы, содержащие целые числа.
Имеем такую разметку:
Альтернативный вариант, если не брать за основу классы - использовать :nth-of-type, который в принципе аналогичен :nth-child, только применяет правило дополнительно привязываясь к тегу(типу), а не всем дочерним элементам. Собственно чтобы этим воспользоваться, все игнорируемые элементы должны быть заключены в тег, отличный от основного тега для подствечиваемых элементов. Например HTML:
...
...
...
...
Здравствуйте, не стану объяснять в чём смысл всего этого кода, и сразу приступлю к проблеме.
Если bar - ArrayList, то операция завершается за 22 секунд, С LinkedList >30 сек. Есть ли другие варианты проверять наличие значения в массиве?
Производительность для меня очень важна :)
Есть код:
final long time = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
foo("test");
}
final long endTime = System.currentTimeMillis();
System.out.println("Time: " + (endTime - time) + " ms");
Метод foo:
public static boolean foo(String s){
/*Всякий код*/
return bar.contains(s);
}
Используйте HashSet.
ArrayList: 14475 ms
HashSet: 43 ms
Sorted ArrayList: 540 ms
Код:
long time = 0;
ArrayList
time = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
strings.contains("test");
}
long endTime = System.currentTimeMillis();
System.out.println("ArrayList: " + (endTime - time) + " ms");
HashSet
Collections.sort(strings);
time = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
Collections.binarySearch(strings,"test");
}
endTime = System.currentTimeMillis();
System.out.println("Sorted ArrayList:" + (endTime - time) + " ms");
У меня есть layout в котором есть CardView внутри которого лежит, скажем, картинка.
Я хочу увеличить высоту и ширину этой CardView вместе с анимацией так как это делают в Material Design Guidelines
Я пробовал 2 способа:
cardView.animate().scaleX().scaleY() - этот способ изменяет размер CardView но вместе с ним и изменяется размер всего, что внутри его даже если у содержимого выставлена специфичная ширина и высота;
можно сделать cardView.getLayoutParams() и потом изменить height и width или можно добавить margin - это действительно меняет размер, но непонятно как это анимировать.
Весьма странно, но я не нашел никаких стоящих рецептов в гугле.
Можно воспользоваться вот этим способом с gitHub-а:
Создаём анимацию изменения параметров View:
public class ResizeAnimation extends Animation {
final int startWidth;
final int targetWidth;
View view;
public ResizeAnimation(View view, int targetWidth) {
this.view = view;
this.targetWidth = targetWidth;
startWidth = view.getWidth();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newWidth = (int) (startWidth + (targetWidth - startWidth) * interpolatedTime);
view.getLayoutParams().width = newWidth;
view.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
Применяем её:
ResizeAnimation resizeAnimation = new ResizeAnimation(view, targetSize);
resizeAnimation.setDuration(600);
view.startAnimation(resizeAnimation);
Слева рисунок это круг используя onDraw и рисовал в Canvas через drawCircle.
А справа круг который создал через drawable circle.xml.
Можно ли сделать так чтобы круг слева был таким же как справа?
Если что могу код скинуть
Вот так, добавить флаг к paint, с помощью которой рисуете:
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Или так:
paint.setAntiAlias(true);
public class Setting
{
public string Setting1 {get;set;}
}
public class SettinngViewModel: ViewModelBase
{
public SettingViewModel(Setting settings)
{
_settings = settings;
}
Setting _settings {get; private set;}
public string Setting1
{
get {return setting1;}
set {setting1=value; OnPropertyChanged("Setting1")}
}
}
собственно вопрос в следующем: есть главная форма из которой вызывается данное окно редактирования настроек
public MainViewModel
{
public MainViewModel()
{
SettingsCommand = new RelayCommand(x=>SettingsMethod());
}
var currentSettings = //здесь хранятся текущие настройки
public ICommand SettingsCommand {get; private set;}
private void SettingsMethod()
{
var view = new SettingsView();
view.DataContext = new SettingsViewModel(currentSettings);
view.Show();
}
}
ввиду того что settings это ссылочный тип то при изменении в окне настроек изменения сразу отражаются в главной форме, а я бы хотел что бы это было только после подтверждения(например пользователь нажимает кнопку Применить)
помогите реализовать соответствующую команду
Смотрите.
Если вы редактируете настройки, вы редактируете, понятно, копию настроек, а не оригинал. В WinForms это скрывалось за тем фактом, что применение изменений происходило во View, но с WPF/MVVM правильный подход такой.
Рассмотрим случай, когда у вас нет VM-объекта, отвечающего за настройки, который поддерживает свои поля в актуальном состоянии. Тогда вам нужен VM-объект «редактируемые настройки» (SettingsEditorVM), который при старте считывает свои свойства из модельного объекта, но не синхронизирует их с моделью при изменениях. Он также выставляет команду «окончить редактирование», по приходу которой проверяет настройки на правильность, и если они в порядке, записывает результат в модельный объект.
Для случая, когда у вас уже есть VM-объект, отвечающий за настройки (SettingsVM), который поддерживает свои поля в актуальном состоянии, вам нужно всё равно завести ещё один VM-объект «редактируемые настройки» (SettingsEditorVM), который сможет загрузить данные (например, в конструкторе) из SettingsVM, и по команде закончить редактирование.
Этим можно пользоваться так:
public class SettinngEditorVM : ViewModelBase
{
public SettinngEditorVM(SettingVM settingsVM)
{
FinishedEditing = new AwaitableCommand();
CancelledEditing = new AwaitableCommand();
Setting1 = settingsVM.Setting1;
}
string setting1;
public string Setting1
{
get { return setting1; }
set
{
setting1 = value;
OnPropertyChanged("Setting1");
CheckCorrectness();
}
}
void CheckCorrectness()
{
bool ok = Setting1 != null;
FinishedEditing.CanExecuteInternal = ok;
}
public AwaitableCommand FinishEditing { get; private set; }
public AwaitableCommand CancelledEditing { get; private set; }
public async Task
с таким вызовом:
var editorVM = new SettingsEditorVM(editorVM);
var task = editorVM.Edit();
var editorWindow = new EditorWindow() { DataContext = editorVM };
editorWindow.Show();
var succeeded = await task;
if (succeeded)
settingsVM.LoadFrom(editorVM);
Заметьте, что код у SettingsEditorVM и SettingsVM практически одинаков, так что эти два класса стоит объединить в один.
Вот код AwaitableCommand
class AwaitableCommand : ICommand
{
bool canExecute;
// не придумал названия получше
public bool CanExecuteInternal
{
get
{
return canExecute;
}
set
{
if (canExecute == value)
return;
canExecute = value;
if (CanExecuteChanged != null)
CanExecuteChanged(this, new EventArgs());
}
}
public bool CanExecute(object parameter)
{
return canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
foreach (var tcs in subscribers)
tcs.TrySetResult(true);
subscribers.Clear();
}
List
public async Task TillActivation(CancellationToken ct)
{
var tcs = new TaskCompletionSource
Приведённый ниже код должен назначить объекту типа Image с помощью прототипа три новых метода: protocol(), host() и pathname()
В браузере FireFox всё проходит нормально. Chrome выдаёт следующую ошибку:
Uncaught TypeError: document.i1.protocol is not a function
Соответственно, и остальные функции document.i1.host и document.i1.path не выполняются.
В чём заключается проблема, и как её решить?
function pr() {
a = this.src.split(':');
return a[0] + ':';
}
function ho() {
a = this.src.split(':');
path = a[1].split('/');
return path[2];
}
function pa() {
path = this.src.split('/');
path[0] = '';
path[2] = '';
return path.join('/').split('///').join('/');
}
Image.prototype.protocol = pr;
Image.prototype.host = ho;
Image.prototype.pathname = pa;
document.write("
");
document.write(document.i1.src + "
");
document.write(document.i1.protocol() + "
");
document.write(document.i1.host() + "
");
document.write(document.i1.pathname() + "
");
Полученный (например, с помощью document.getElementById('img') или new Image()) имеет тип HTMLImageElement. Соответственно, добавлять новые методы нужно именно в его прототип.
Пример:
function log(info) {
document.body.innerHTML += info + "
";
}
HTMLImageElement.prototype.protocol = function() {
log("Protocol is called");
};
var img = document.getElementById('img');
log("Got image: " + img.constructor.name);
img.protocol();
var newImage = new Image();
log("New image: " + newImage.constructor.name);
newImage.protocol();
Настройка виртуального хоста:
ServerName test.loc
ServerAdmin webmaster@test.loc
DocumentRoot /home/r/www/test.loc/web
ErrorLog /home/r/www/logs/test.loc/error.log
CustomLog /home/r/www/logs/test.loc/access.log combined
Дополнительные настройки сервера (кроме тех, что были по умолчанию):
## Файл персональных настроек веб-сервера Apache от Razzwan-a
## Чтобы устранить предупреждение при перезапуске Apache (хотя в целом на производительности это не отразится)
ServerName test.loc
## Для того, чтобы Apache интерпретировал php и не предлагал сохранить php-файл
AddType application/x-httpd-php .php .phtml
## Установка кодировки по умолчанию
AddDefaultCharset UTF-8
## Настройка базовой директории
Права на папку, из которой грузится сайт (/home/r/www) 777.
И все равно выдает ошибку:
[Thu Dec 10 10:52:54.723123 2015] [core:error] [pid ****] (13)Permission denied: [client 127.0.0.1:] AH00035: access to / denied (filesystem path '/home/r/www') because search permissions are missing on a component of the path
[Thu Dec 10 10:52:54.792334 2015] [core:error] [pid *****] (13)Permission denied: [client 127.0.0.1:] AH00035: access to /favicon.ico denied (filesystem path '/home/r/www') because search permissions are missing on a component of the path, referer: http://test.loc:81/
Apache пробовал запускать от того же пользователя, которому принадлежать файлы сайта - никаких изменений.
Что еще можно проверить, глянуть? Уже просто нет идей.
filesystem path '/home/r/www') because search permissions are missing on a component of the path
у какого-то из компонентов в этом пути не хватает атрибута x для пользователя, от имени которого работает у вас apache
исправить можно, например, так (на всякий случай добавляется и атрибут r — право на чтение):
$ sudo chmod +rx /home /home/r /home/r/www
Require all granted
директива require появилась только в версии 2.4 программы apache
если у вас, как указано с помощью меток, версия 2.2, то следует использовать директиву allow. например:
allow from all
Как с помощью java запустить графическое приложение из Linux, тоесть получить доступ к консоли.
Используйте ProcessBuilder
ProcessBuilder builder = new ProcessBuilder("gedit");
Process process = builder.start();
Если у программы есть параметры, их нужно прописать через запятую
ProcessBuilder builder = new ProcessBuilder("gedit","a.txt");
Process process = builder.start();
В классе определена операция /. Пишу x=a/*this.
/* интепретируется как комментарий. Что делать?
x = a / *this;
или, в Вашем стиле:
x=a/ *this;
А можно ещё вот так:
x=a/(*this);
Пишу маленькое приложение на Android на Java. У меня пользователи в одном активити проходят тест и, по завершению теста, открывается следующее активити, в которое передается итоговая инфа по прохождению теста. Так вот, одно из полей - это потраченное время на задание... я пробую считать время хронометром, но он в миллисекундах считает и потом форматировать через различные проверки в формат 00:00 (02 : 34), очень костыльно получается... Я уверен, что есть более изящное решение...
Как это можно сделать?
В начале задания сохраняйте текущее время в long переменную:
long startTime = System.currentTimeMillis();
После окончания получайте разницу:
long totalTime = System.currentTimeMillis() - startTime;
Берём класс Calendar и присваиваем ему полученное значение:
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis( totalTime );
Получаем минуты/секунды (без нулей в начале):
int minutes = cal.get(Calendar.MINUTE);
int seconds = cal.get(Calendar.SECOND);
или в форматированном виде с помощью класса SimpleDateFormat
SimpleDateFormat format = new SimpleDateFormat("mm:ss");
System.out.println(format.format(cal.getTime()));
Допустим есть такая таблица:
id|name|number
1 |Igor|89172281212
2 |Petr|89274554545
3 |Andr|89172281212
Подскажите, как составить sql-код, который выведет 1 и 2 строчку, а 3 не надо, т.к. их телефоны (с 1м) одинаковые.
Можно явно исключить лишние записи. Только надо определится по какому конкретно условию исключать. Вернее какая из записей с данным телефоном может быть более интересна. Например
select * from Table as A
where not exists(select 1
from Table as B
where B.number=A.number and B.id
У меня есть Type атрибута. Я разбираю Assembly по типам, которые имеют нужный атрибут.
types = ass.GetTypes().Where(t => t.CustomAttributes.Any(a => a.AttributeType == utilTypes[1]));
То есть получаю список типов. Мне нужно, перебирая этот список, достать свойства атрибута. Ну например вот из этого
[MyAttribute("Hello")]
class MyClass{}
мне нужно достать свойство Prop1, которое равно "Hello". Как это сделать? Чего то уже совсем запутался в этих рефлекциях :(
UPD1
Забыл сказать. У меня нет прямого доступа к типу атрибута. То есть я не могу сделать так
foreach (var type in types)
{
var MyAttr = (MyAttributeAttribute)type.GetCustomAttribute(utilTypes[0].GetType())
}
Потому что этот самый тип атрибута MyAttributeAttribute я имею только в текстовом виде. А значит мне нужно каким то образом достать из него свойство, к которому я не имею прямой доступ
Попробуйте следующий подход.
Пусть тип экземпляра класса MyClass лежит в переменной type. То есть:
Type type = typeof(MyClass);
Или в вашем случае:
Type type = types[i];
Тогда следующий код:
var attr = type.CustomAttributes.FirstOrDefault(a => a.AttributeType == utilTypes[0]);
if (attr != null)
{
var attrType = attr.AttributeType;
var propInfo = attrType.GetProperty("Prop1", BindingFlags.Instance | BindingFlags.Public);
Console.WriteLine(propInfo.GetValue(mcType.GetCustomAttribute(attrType)));
}
Выведет:
Hello
Вот, оформил в виде метода:
public static object GetAttributeProperty(Type classType, Type attributeType, string propertyName)
{
var propInfo = attributeType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public);
return propInfo.GetValue(classType.GetCustomAttribute(attributeType));
}
Есть шаблонный класс вектора:
template< int size, typename Type >
class Vector;
Есть шаблонный оператор для сложения двух векторов:
template< int size, typename LeftType, typename RightType >
Vector
Который, по задумке, должен работать с любыми типами векторов, лишь бы они были одного размера. Чтобы можно было сложить Vector<3, int> и Vector<3, double>. Но встает вопрос - как определить результирующий тип вектора, чтобы точность не терялась?
Например для int и double логично было бы выбрать double, для int и float - float, для float и double - double. Как этого можно добиться, не прописывая шаблон для каждого случая?
Вы можете использовать std::common_type.
Ниже показана демонстрационная программа. Я объявил класс Vector с минимальными свойствами, чтобы лишь продемонстрировать использование std::common_type
#include
template< int size, typename Type >
struct Vector
{
std::vector
template< int size, typename LeftType, typename RightType >
Vector
for ( int i = 0; i < size; i++ ) v.v[i] = left.v[i] + right.v[i];
return v;
}
int main()
{
Vector<5, int> left = { { 1, 2, 3, 4, 5 } };
Vector<5, double> right = { { 0.1, 0.2, 0.3, 0.4, 0.5 } };
auto v = left + right;
for ( int i = 0; i < 5; i++ ) std::cout << v.v[i] << ' ';
std::cout << std::endl;
}
Ее вывод на консоль:
1.1 2.2 3.3 4.4 5.5
Есть DropDownlist c отступом:
Все
XXX
XXX
XXX
XXX
XXX
Запрос:
declare
@name nvarchar(100) = ' XXX'
begin
SET NOCOUNT ON;
SELECT [id]
,[name]
FROM dbo.test
where (@name = 'Все' or name Like '%'+@name+'%')
end
В таблице есть строка XXX без отступа.
В параметр @name передается значении с пробелами(к примеру ' XXX', ' XXX')
Как сделать чтобы оператор like работал?
Если проблема в пробеле - то проще всего его обрезать:
declare
@name nvarchar(100) = ' XXX'
begin
SET NOCOUNT ON;
SELECT [id]
,[name]
FROM dbo.test
where (@name = 'Все' or name Like '%'+RTRIM(LTRIM(@name))+'%')
end
Пишу программу на C# с mvvm. У меня есть два эквивалентных куска кода, в которых,по-моему мнению, должна происходить абсолютно одинаковая работа. Суть в чем- постепенная подгрузка(добавление) элементов в коллекцию с помощью BackgroundWorker. Коллекция имеет биндинг с listview и соответственно постепенное(пообъектное) добавление в коллекцию отображается в этом listview.
Код:
public class ListContactViewModel : ViewModelBase
{
public ObservableCollection
DialogListFirstPage = new ObservableCollection
};
bw1.RunWorkerAsync();
//внимания в этом методе достойна только строчка добавления в коллекцию
private void FirstDialogPageMethod(VkApi vk)
{
int totalCount, unreadCount;
var GetFirstDialigPage = vk.Messages.GetDialogs(20, 0, out totalCount, out unreadCount);
foreach (var i in GetFirstDialigPage)
{
var Names = vk.Users.Get(i.UserId.ToString(), ProfileFields.FirstName);
_dispatcher.Invoke(()=> DialogListFirstPage.Add(new MessageChild() { AuthorFirstName = Names.FirstName, AuthorLastName = Names.LastName, Body = i.Body, UserId = i.UserId, Date = i.Date, ChatActiveIds = i.ChatActiveIds, Title = i.Title, UsersCount = i.UsersCount, ChatId = i.ChatId }));
}
}
на всякий случай приведу строчку биндинга из xaml:
И все закономерно: окно открывается пустым и я наблюдаю постоянное добавление элементов в список.
Ситуация 2: Из предыдущего окна я перехожу в следующее , в котором аналогичная ситуация
public class CurrentDialogViewModel:ViewModelBase
{
public ObservableCollection
MoreMessages();
};
bw2.RunWorkerAsync();
private void MoreMessages()
{
foreach (var i in builder.ConcreateDialogCreater(ids))
{
disp.Invoke(() => ReadyCollection.Insert(0, i));
}
Datas.offset += 200;
}
где builder.ConcreateDialogCreater(ids) возвращает
ObservableCollection
Xaml:
Так вот в этом случае при открытии окна, оно у меня некоторое время остается пустым, после чего список мгновенно отображает все объекты в ReadyCollection.
От Insert это не зависит, с Add тоже самое. Также это не зависит от builder.ConcreateDialogCreater(ids), потому что пробовал делать просто инициализацию объекта при добавлении в цикле
ReadyCollection.Add(new MessageChild());
Аналогичная история-объекты вываливаются всем скопом по окончании добавления последнего. А я хочу добиться постепенной подгрузки, как в предыдущем окне.
Почему так происходит и что нужно исправить?
UPD:
Продебажил еще раз - все таки я был не прав и задержка связана с выполнением метода builder.ConcreateDialogCreater(ids). И пока он не выполнится весь- foreach не начнется.
Ведь в первом случае я коллекцию заполняю непосредственно в том классе и задержка обоснована работой библиотечных методов перед добавлением.
Во-втором же случае нужно ждать,пока метод выполнится полностью.
В DoWork вместо Dispatcher используйте ReportProgress.
(для его работы надо включить WorkerReportsProgress).
partial class MainWindow : Window {
public MainWindow() {
this.DataContext = _List = new ObservableCollection
ObservableCollection
private void Button_Click(object sender, RoutedEventArgs e) {
var w = new BackgroundWorker() { WorkerReportsProgress = true };
w.DoWork += (s, we) => {
for (var i = 0; i < 50; i++) {
Thread.Sleep(100); // тут что-то делаем
w.ReportProgress(0, i);
}
};
w.ProgressChanged += (s, we) => // выполняется в основном потоке
_List.Add(new Message() { Text = "t" + we.UserState });
w.RunWorkerAsync();
}
class Message {
public string Text { get; set; }
}
}
Не принимает id переменная.
Есть код, который при нажатии на объект(в моем случае я нажимаю на изображения) получает id этого объекта:
var id;
document.querySelector('#rm').addEventListener('click', function(e){ // Вешаем обработчик клика на UL, не LI
id = e.target.id; // Получили ID, т.к. в e.target содержится элемент по которому кликнули
});
И мне нужно полученное id поместить в переменную, чтобы через нее получить адрес изображения. Я делаю это так :
var a = document.getElementById(id);//получаю доступ к его свойствам
var canvas = document.getElementById('canvas_picker').getContext('2d');
// create an image object and get it’s source
var img = new Image();
img.src = a.src; // помещаю адрес картинки. Тут у меня и не работает!!!
// copy the image to the canvas
$(img).load(function(){
canvas.drawImage(img,0,0);
});
Весь код, который при клике на любой участок изображение можно получить код цвета в HEX и RGB:
var canvas = document.getElementById('canvas_picker').getContext('2d');
// create an image object and get it’s source
var img = new Image();
img.src = a.src; // помещаю адрес картинки. Тут у меня и не работает!!!
// copy the image to the canvas
$(img).load(function(){
canvas.drawImage(img,0,0);
});
// http://www.javascripter.net/faq/rgbtohex.htm
function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)}
function toHex(n) {
n = parseInt(n,10);
if (isNaN(n)) return '00';
n = Math.max(0,Math.min(n,255));
return '0123456789ABCDEF'.charAt((n-n%16)/16) + '0123456789ABCDEF'.charAt(n%16);
}
$('#canvas_picker').click(function(event){
// getting user coordinates
var x = event.pageX - this.offsetLeft;
var y = event.pageY - this.offsetTop;
// getting image data and RGB values
var img_data = canvas.getImageData(x, y, 1, 1).data;
var R = img_data[0];
var G = img_data[1];
var B = img_data[2]; var rgb = R + ',' + G + ',' + B;
// convert RGB to HEX
var hex = rgbToHex(R,G,B);
// making the color the value of the input
$('#rgb input').val(rgb);
$('#hex input').val('#' + hex);
});
Из приведённых фрагментов кода не совсем понятно, какая часть из них находится внутри обработчика событий кликов по изображениям (или вы действительно только меняете id?). У меня ваш код работает в таком виде:
var id, img, a,
canvas = document.getElementById('canvas_picker').getContext('2d');
document.querySelector('#rm').addEventListener('click', function(e) {
id = e.target.id;
a = document.getElementById(id);
img = new Image();
$(img).load(function(){
canvas.drawImage(img,0,0);
});
img.src = a.src;
});
https://jsfiddle.net/du5ns2ug/
При получении почтового сообщения с Mail.ru message.getContent() или message.isMimeType("text/plain") вызывает возникновение NPE, хотя тема и отправитель читаются корректно. С Яндекса все хорошо, с gmail тоже.
Сообщение отправляется с браузера (с Gmail), а не программно.
Сталкивался ли кто-то с таким? Код стандартный:
private Session session(String protocol, String host, Integer port) {
final Properties properties = new Properties();
properties.put("mail.store.protocol", protocol);
properties.put(String.format("mail.%s.host", protocol), host);
properties.put(String.format("mail.%s.port", protocol), String.valueOf(port));
properties.setProperty(String.format("mail.%s.socketFactory.class", protocol), "javax.net.ssl.SSLSocketFactory");
properties.setProperty(String.format("mail.%s.socketFactory.fallback", protocol), "false");
properties.setProperty(String.format("mail.%s.socketFactory.port", protocol), String.valueOf(port));
properties.setProperty("mail.mime.decodetext.strict", "false");
return Session.getInstance(properties);
}
public synchronized List
store = session.getStore(protocol);
store.connect(host, username, password);
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
final Message[] messages = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
return Lists.newArrayList(messages);
}
Stack Trace:
Caused by: java.lang.NullPointerException: null
at javax.mail.internet.MimeUtility.quote(MimeUtility.java:975) ~[mail-1.4.7.jar:1.4.7]
at javax.mail.internet.ParameterList.quote(ParameterList.java:672) ~[mail-1.4.7.jar:1.4.7]
at javax.mail.internet.ParameterList.access$200(ParameterList.java:76) ~[mail-1.4.7.jar:1.4.7]
at javax.mail.internet.ParameterList$ToStringBuffer.addNV(ParameterList.java:640) ~[mail-1.4.7.jar:1.4.7]
at javax.mail.internet.ParameterList.toString(ParameterList.java:621) ~[mail-1.4.7.jar:1.4.7]
at javax.mail.internet.ContentType.toString(ContentType.java:221) ~[mail-1.4.7.jar:1.4.7]
at com.sun.mail.imap.IMAPMessage.getDataHandler(IMAPMessage.java:644) ~[mail-1.4.7.jar:1.4.7]
at javax.mail.internet.MimeMessage.getContent(MimeMessage.java:1420) ~[mail-1.4.7.jar:1.4.7]
at com.brooma.legalsm.task.manager.util.MailParser.plainText(MailParser.java:44) ~[legalsm-task-manager-1.0.jar:na]
at com.brooma.legalsm.task.manager.util.MailParser.
Это баг: https://kenai.com/bugzilla/show_bug.cgi?id=5978
Для решения необходимо использовать версию 1.5.5 и следующую зависимость:
Имею следующий код
static void Main(string[] args)
{
string value = "value1";
// switch с const переменными работает
switch(value)
{
case ConstVariable.VALUE1:
Console.WriteLine(ConstVariable.VALUE1);
break;
case ConstVariable.VALUE2:
Console.WriteLine(ConstVariable.VALUE2);
break;
case ConstVariable.VALUE3:
Console.WriteLine(ConstVariable.VALUE3);
break;
}
// ЗДЕСЬ ОШИБКА!!! switch c readonly переменными не работает
switch (value)
{
case ReadOnlyVariable.VALUE1:
Console.WriteLine(ConstVariable.VALUE1);
break;
case ReadOnlyVariable.VALUE2:
Console.WriteLine(ConstVariable.VALUE2);
break;
case ReadOnlyVariable.VALUE3:
Console.WriteLine(ConstVariable.VALUE3);
break;
}
}
static class ReadOnlyVariable
{
public static readonly string VALUE1 = "value1";
public static readonly string VALUE2 = "value2";
public static readonly string VALUE3 = "value3";
}
static class ConstVariable
{
public const string VALUE1 = "value1";
public const string VALUE2 = "value2";
public const string VALUE3 = "value3";
}
В блоке switch я могу использовать переменные const, но если я использую переменны readonly, то получаю ошибку
A constant value is expected
Почему так, разве переменные readonly на этапе компиляции не определяются?
readonly значит, что поле должно быть инициализировано в конструкторе и последующая модификация данного поля запрещена. Т.е. это гарантия того, что раз поле проинициализировано в конструкторе, оно больше не может быть изменено в других частях класса. Но это не делает его сущностью времени компиляции — нет, оно защищено от переинициализации, но не является константным.
Подробнее в документации
Некоторые CMS используют для хранения статей не базу данных, а обычные текстовые файлы. Хотелось бы узнать, какие в этом случае могут возникнуть проблемы при большом количестве статей.
Пока единственное, что приходит на ум - это поиск, но при желании и его можно ускорить, если создавать индекс.
PS. Одним таким движком я давно уже пользуюсь и доволен, но статей на данный момент не очень много.
Резервная копия. Придётся файлы копировать отдельно от базы. Если в
это время происходят транзакции, то файлы могут оказаться немного не
синхронизированными с базой.
Индексация. Многие базы поддерживают полнотекстовый поиск и
соответствующие индексы. По своим полям они точно ищут и
индексируют, а вот внешние файлы - кто знает? Хотя конечно можно
сделать поля специально для хранения индекса (грубо говоря из текста
извлечь ключевые слова и поместить в это поле).
Переключение с одной методы получения/записи данных на другую. Это
просто неудобство. В некоторых случаях оно так и так будет (если
пользоваться не привычным SELECT/INSERT, а каким-то более
эффективным на больших данных поточным интерфейсом базы данных)
В любом случае приходится предпринимать дополнительные усилия по синхронизации записей в БД и внешних файлов. Где это действительно важно, требуется задействовать базы данных и файловые системы с поддержкой распределённых транзакций, координировать транзакции бд и фс.
Не понял в чем различия между паттернами 'абстрактная фабрика' и 'строитель'. На основе каких критериев выполняется выбор? Какие вопросы я должен задать себе, что бы понять какой порождающий паттерн из двух приведенных мне использовать?
Абстрактная фабрика предоставляет интерфейс для создания семейств, связанных между собой, или независимых объектов, конкретные классы которых неизвестны.
Строитель отделяет конструирование сложного объекта от его представления, позволяя использовать один и тот же процесс конструирования для создания различных представлений
Основное различие между ними в том, что строитель делает акцент на пошаговом конструировании объекта, а абстрактная фабрика на создании семейств объектов. Строитель возвращает объект на последнем шаге, тогда как с точки зрения абстрактной фабрики продукт возвращается немедленно.
Нужно написать команду, которая бы удаляла все файлы расширения .txt из папки /home/u20806/public_html, которые были созданы или изменены 25 минут назад.
Сделал так: find /home/u20806/public_html -daystart -maxdepth 1 -mmin +25 -type f -name "*.txt" \ -exec rm -f {} \;
Выдает ошибку find: path must precede expression:
Usage: find [-H][-L][-P][-Olevel][-D help|tree|search|stat|rates|opt|exec][path...][expression]
Как переписать?
я вижу в этой команде две ошибки и одну неоптимальность:
find /home/u20806/public_html -daystart -maxdepth 1 -mmin +25 -type f -name "*.txt" \ -exec rm -f {} \;
во-первых, благодаря опции -daystart программа find «найдёт» не совсем то, что вам требуется: время (указанное опцией -mmin) будет «отсчитываться» не от текущего момента, а от начала этого дня (см. внимательней на описание опции -daystart в man find).
во-вторых, параметр \ между -name и -exec не нужен и порождает описанную ошибку.
в-третьих, и действие -exec ... лучше заменить на действие -delete.
резюмируя, предложу написать, например, так:
find /home/u20806/public_html -maxdepth 1 -mmin +25 -type f -name "*.txt" -delete
Основная задача - узнать размер файла. Изначально в проекте пользовался du -b file.txt. Проект переехал на BusyBox. Теперь у команды du нет опции -b. Каким образом еще можно посчитать размер файла в байтах.
Для получения подробной информации о файлах надо использовать команду stat
stat имя-файла -c %s
Для получения информации в том же виде, как выдает du -b т.е. с именем файла после размера, можно использовать формат -c "%s %n"
Как можно с помощью лямбда-выражений прочитать текстовый документ по ссылке? Т.е. создается объект URL url = new URL("http://www.nkode.io/assets/programming/countmychars.txt"); Но как читать содержимое документа с помощью лямбды?
Окей, если я правильно понял ваш вопрос, вы хотите читать текст из URL построчно, получив stream на список строк. (То есть, аналог кода BufferedReader input = ...; while( (line == input.readline()) != null) ....)
Это делается так (код одолжен в этом ответе):
try (InputStream is = new URL("http://www.nkode.io/assets/programming/countmychars.txt")
.openConnection().getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
Stream
В одном пакете находятся Vector - interface и Vect - class. Причем класс имплементирует интерфейс. А в классе есть методы, которые возвращают тип Vector, то есть интерфейса. Какой в этом смысл?
Чтобы не завязываться на конкретную реализацию. Отчасти это принцип инкапсуляции. За счёт использование интерфейса в возвращаемом методе, тот, кто будет использовать класс, будет обращать внимание только на интерфейс, ему не важна реализация оного. Это уменьшает связанность компонентов.
К примеру:
public interface Vector{
public Vector rotateAndReturn();
public Vector somethingAndReturn();
[...]
}
public class Vect implement Vector{
public Vector rotateAndReturn(){
// поворачиваем
return this;
}
public Vector somethingAndReturn(){
// что-то делаем
return this;
}
}
Зачем? Смысл появится, когда, к примеру, новую реализацию Vector захотите делать:
public class SuperVect implement Vector{
public Vector rotateAndReturn(){
// поворачиваем
return this;
}
public Vector somethingAndReturn(){
// что-то делаем
return this;
}
}
Теперь можно так:
Vector vector = new Vect();
vector1.rotateAndReturn().somethingAndReturn();
Можно тогда экземпляр другого класса создать и так же вызывать:
vector = new SuperVect ();
vector1.rotateAndReturn().somethingAndReturn();
Плюшка в использовании коллекции:
List
Теперь при прогонке мы с классами можем унифицировано работать:
list.forEach(vector -> vector.rotateAndReturn().somethingAndReturn());
Независимо от того, какой это объект на самом деле, за счёт того, что методы возвращают имплементируемый интерфейс, мы работаем с классами унифицировано.
Как предотвратить распространение стилей на все вложенные элементы?
.extend_test{
background: #972b2b;
color: slateblue;
}
Единственный способ — это сбрасывать отнаследованные значения на потомках на значения по умолчанию, которые могут варьироваться от браузера к браузеру.
Применение CSS к документам HTML основано на принципах наследования
и каскадирования. Википедия
Есть приложение на с++, которое пишет данные в лог.
Используется syslog(LOG_INFO,"Init"), к примеру. Данные записываются в /var/log/messages
При перезагрузке системы данные из /var/log/messages удаляются.
Есть ли способ сделать так, чтобы логи не удалялись? Предполагаю, что нужно использовать syslog.conf
Как можно решить проблему?
Операционная система: busybox/linux
это, вероятно, т.н. «embedded»-система. и каталог /var (или только /var/log) находится на временной файловой системе (скорее всего, типа tmpfs), которая расположена в оперативной памяти, и создаётся при загрузке системы.
пример проверки (это дистрибутив openwrt):
$ df /var
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 63268 380 62888 1% /tmp
$ ls -ld /var
lrwxrwxrwx 1 root root 4 Sep 17 2013 /var -> /tmp
делается это с целью сохранения ресурса накопителя информации, который в таких устройствах обычно может выдержать довольно ограниченное количество операций записи.
не зная подробностей об используемом вами дистрибутиве, могу предположить лишь такие общие варианты решения:
изменить вашу программу, чтобы она писала данные в файл, расположенный на блочном устройстве хранения информации;
изменить систему инициализации вашего дистрибутива так, чтобы каталог /var или /var/log или хотя бы файл /var/log/messages располагался не в памяти, а на блочном устройстве;
изменить конфигурацию используемого вами системного логгера так, чтобы он записывал не в файл /var/log/messages, а в файл, расположенный на блочном устройстве. или, например, отсылал логируемую информацию по сети на другой компьютер.
Как работают указатели?
Что будет в итоге, если я напишу так?
HANDLE * VariableHandle;
DWORD * VariableDword;
или так?
HANDLE VariableHandle;
DWORD VariableDword;
Пример из исходных кодов других программ.
Почему так?
int chSizeOfArray(char *chArray);
int iSizeOfArray(int *iArray);
А не так?
int chSizeOfArray(char chArray);
int iSizeOfArray(int iArray);
Когда вы пишете HANDLE * VariableHandle;, вы объявляете, что в переменной VariableHandle будет содержаться указатель на HANDLE. А объявление HANDLE VariableHandle; означает, что в переменной VariableHandle будет содержаться сам HANDLE
В языках типа C указатель используется во многих смыслах. Один из них — это массив элементов. Функции int f1(char *chArray); и int f2(char ch); обе возможны, но при этом f1 принимает в качестве аргумента массив char'ов (или указатель на один char, это уж как в документации написано), а f2 — один char
Как верно подсказывает @ixSci, лучше всего думать про указатель как про адрес объекта. Если представить себе всю память как огромный массив байт, адрес — это просто номер начального байта, занимаемого данными, в этом массиве. (Это несколько упрощённая картина, но для начала то, что нужно.)
Есть строка с SDP информацией, содержащей всю нужную информацию по кодекам. Не хочется создавать для нее файл, передавать его в avformat_open_input, а затем удалять и так каждый раз. А надо бы разбирать sdp-строку и настраивать тип входящего кодека и проч. без создания файла. Я не нашел функционала ffmpeg, который бы со строки инитил бы кодеки. Может, кто-то знает его? Или придется писать свой парсер и вручную настраивать кодеки?
Смотря что понимать под нужным функционалом. Ты можешь созать свой AVIO контекст, а он, в качестве источника данных, может хоть базу данных, хоть общую память, хоть просто кусок памяти использовать.
Курить:
avio_alloc_context()
AVFormatContext::pb
avformat_open_input()
Т.е. алгоритм ваших действий будет примерно такой:
Аллоцировать AVFormatContext (avformat_alloc_context())
Аллоцировать AVIOContext с нужными функциями, и структурой контекста
Присвоить AVFormatContext::pb значение вашего контекста IO
Вызвать avformat_open_input() где первым параметром передать указатель на ваш, уже аллоцированный, контекст формата - он любезно им воспользуется.
При вызове вашей процедуры чтения вполне возможно, что запросится только часть данных, поэтому нужно где-то хранить позицию чтения (opaque вам в помощь) и контроллировать границу данных (когда у вас осталось, допустим, 2 байта, а запросили буфер 1024 - записать только 2 и вернуть реальное число записанный байт, т.е. снова - 2).
А вот и рабочий, компилируемый (GCC 4.9, FFmpeg 2.8.6) пример:
#include
extern "C" {
#include
using namespace std;
static const char* SDP_DATA = R"(
v=0
o=- 1376063087593 1 IN IP4 127.0.0.1
s=-
t=0 0
m=audio 50008 RTP/AVP 0
c=IN IP4 192.168.2.196
a=rtcp:50009 IN IP4 192.168.2.196
a=rtpmap:0 PCMU/8000
a=sendrecv
m=video 50010 RTP/AVP 120
c=IN IP4 192.168.2.196
a=rtcp:50011 IN IP4 192.168.2.196
a=rtpmap:120 VP8/90000
a=sendrecv
a=rtcp-fb:* nack
a=rtcp-fb:* ccm fir
)";
struct SdpOpaque
{
using Vector = std::vector
int sdp_read(void *opaque, uint8_t *buf, int size) noexcept
{
assert(opaque);
assert(buf);
auto octx = static_cast
if (octx->pos == octx->data.end()) {
return 0;
}
auto dist = static_cast
std::copy(octx->pos, octx->pos + count, buf);
octx->pos += count;
return count;
}
int sdp_open(AVFormatContext **pctx, const char *data, AVDictionary **options) noexcept
{
assert(pctx);
*pctx = avformat_alloc_context();
assert(*pctx);
const size_t avioBufferSize = 4096;
auto avioBuffer = static_cast
opaque->data = SdpOpaque::Vector(data, data + strlen(data));
opaque->pos = opaque->data.begin();
auto pbctx = avio_alloc_context(avioBuffer, avioBufferSize, 0, opaque, sdp_read, nullptr, nullptr);
assert(pbctx);
(*pctx)->pb = pbctx;
auto infmt = av_find_input_format("sdp");
return avformat_open_input(pctx, "memory.sdp", infmt, options);
}
void sdp_close(AVFormatContext **fctx) noexcept
{
assert(fctx);
auto ctx = *fctx;
// Opaque can be non-POD type, free it before and assign to null
auto opaque = static_cast
avio_close(ctx->pb);
avformat_close_input(fctx);
}
int main()
{
av_register_all();
avformat_network_init();
AVFormatContext *sdpctx = nullptr;
sdp_open(&sdpctx, SDP_DATA, nullptr);
av_dump_format(sdpctx, 0, "memory.sdp", 0);
// Copy settings to target context from SDP context:
/*
for (size_t i = 0; i < sdpctx->nb_streams; ++i) {
AVStream *st = avformat_new_stream(otherctx, nullptr);
st->id = i;
avcodec_copy_context(st->codec, sdpctx->streams[i]->codec);
st->time_base = sdpctx->streams[i]->time_base;
}
*/
sdp_close(&sdpctx);
return 0;
}
После запуска выводит:
Input #0, sdp, from 'memory.sdp':
Metadata:
title : -
Duration: N/A, bitrate: N/A
Stream #0:0: Audio: pcm_mulaw, 8000 Hz, 1 channels, 64 kb/s
Stream #0:1: Video: vp8, none, 90k tbn
Собственно, что и описано в SDP.
Хочу заменить char на пустую, но не знаю как. Интересует что-то подобное String.Empty
private string replace(string hex, string input)
{
int decValue = Convert.ToInt32(hex, 16);
string result = input.Replace((char)decValue, ' ');
return result;
}
String.Empty - строка нулевой длины, символ же не может быть нулевой длины. Самое близкое, что можете использовать - '\0'. Но строка от этого короче не станет. Тогда уж лучше так: string result = input.Replace(((char)decValue).ToString(), "");
Имеется PiCamera с RPi. Пытаюсь написать Python код для управления камерой с помощью веб. В данный момент мой код выглядит вот так
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Test version
'''
from flask import Flask
from datetime import datetime
import io
import time
import picamera
import logging
import sys
import os
app = Flask(__name__)
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)-8s '
+ '[%(filename)s:%(lineno)s:%(funcName)s()] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
@app.route("/start", methods=['POST'])
def start_capture():
with picamera.PiCamera() as camera:
camera.resolution = (1920, 1080)
camera.start_preview()
time.sleep(300)
@app.route("/stop", method=['POST'])
def stop_capture():
with picamera.PiCamera() as camera:
camera.stop_preview()
@app.route("/screenshot", methods=['POST'])
def screenshot():
with picamera.PiCamera() as camera:
camera.capture('foo.jpg', use_video_port=True)
if __name__ == "__main__":
app.run(host='192.168.0.198', port='8080')
Первое что не работает правильно - если я отправляю POST запрос к примеру на 192.168.192:8080/start, запрос отправляется бесконечно.
Далее есть после старта, отправить запрос на стоп, ничего не происходит. Где я что, сделал не правильно? Есть ли способ, каким-то образом записать все в одну функцию, но при это вызывать разным запросом определенные части функции?
Попробую угадать ответ по документации picamera. Согласно ей, при входе в with-блок камера включается, а при выходе выключается, то есть получается:
@app.route("/start", methods=['POST'])
def start_capture():
with picamera.PiCamera() as camera: # Включили камеру
camera.resolution = (1920, 1080)
camera.start_preview()
# with закончился — выключили камеру
Отсюда вывод: надо как-то держать камеру постоянно включенной независимо от http-запросов. Простейший способ — вынести camera в глобальную переменную, где она и будет лежать включенная независимо от http-запросов:
from threading import Lock
import picamera
camera = None # Сразу после запуска камера выключена
camlock = Lock() # Блокировка нужна, чтобы нельзя было
# лезть в камеру из нескольких запросов одновременно
# ... app = Flask(__name__) logging всё такое скопировать сюда из вопроса #
@app.route("/start", methods=['POST'])
def start_capture():
global camera
with camlock:
if camera:
return 'already started'
camera = picamera.PiCamera()
camera.resolution = (1920, 1080)
return 'ok'
@app.route("/stop", methods=['POST'])
def stop_capture():
global camera
with camlock:
if not camera:
return 'already stopped'
camera.close()
camera = None
return 'ok'
@app.route("/screenshot", methods=['POST'])
def screenshot():
# Переменную не меняем — global необязателен
with camlock:
if not camera:
return 'camera is not started'
camera.capture('foo.jpg', use_video_port=True)
return 'saved to foo.jpg'
if __name__ == "__main__":
try:
app.run(host='192.168.0.198', port='8080')
finally:
# При завершении работы http-сервера камеру стоит выключить
with camlock:
if camera:
camera.close()
Raspberry Pi не имею и проверить работоспособность кода не могу, но вроде не должен был накосячить.
(Замечание 1: глобальные переменные — довольно опасная штука, и при увеличении сложности проекта от них можно начать получать множество проблем, когда они начнут меняться непредсказуемо и всё такое.)
(Замечание 2: возможно, более хорошим решением будет запуск второго потока, который и будет обслуживать камеру (без глобальной переменной) и принимать сообщения-команды от http-сервера из первого потока вместо непосредственного доступа к камере, но это увеличивает сложность и не факт что целесообразно в данном случае.)
Пишу плагин, который на текущей вкладке вызывает скрипт, который заполняет определенные поля (имя, телефон, адрес и т.п.).
Как сделать сохранение этих значений?
В идеале: забить их в каком-то файле (например, в json) и при запуске скрипта для вкладки вытаскивать их.
Цель -- один раз заполнить поля, чтобы плагин их находил, главное, чтобы после перезапуска firefox'а они не потерлись.
Делаю для себя, но прописывать внутри кода эти значения не хочу -- отсутствие гибкости и выкладывание личной инфы.
Потом бы добавил к плагину простой интерфейс для заполнения тех полей.
Есть еще один способ хранить настройки плагинов: simple-prefs
Нужно в package.json добавить поле preferences и в него добавить свои параметры. После, эти параметры будут доступны в настроках плагина в about:addons. При изменении настройки сохраняются, включая между запусками браузера.
UPDATE:
Плагин работает!
Исходник плагина: создание кнопки плагина и заполнение полей.
Значения полей берутся из настроек плагина
Как программно закрыть приложение полностью, т.е. удалить его из памяти так, как сделал бы сам андроид при нехватке ресурсов?
Попробуйте finishAffinity() - метод закрывает все Activity в стеке. Правда, минимальная версия API - 16
Когда используется одно, а когда другое? С виду эти контракты очень похожи
В общих чертах:
Соглашения (Contracts) в WCF предоставляют совместимость, необходимую для взаимодействия с клиентом. DataContract и MessageContract являются структурными соглашениями (structural contracts), которые дополняют друг друга и служат разным целям.
DataContract - это соглашение между сторонами (сервисом и клиентом), которое описывает тип данных, которым они будут обмениваться, иными словами DataContract используется для определения структуры данных сообщения, т.е. DataContract определяет какие параметры и возвращаемые типы будут сериализованы/десериализованы Binary <==> XML для обмена между сторонами.
WCF использует SOAP-сообщения для общения. MessageContract используется для контроля структуры тела SOAP-сообщения (SOAP message body) и сериализации данных, а так же для передачи информации в заголовках SOAP-сообщений (SOAP header).
Таким образом, использование MessageContract предпочтительно только тогда, когда существует необходимость контролировать "макет" вашего сообщения (SOAP-сообщения). Например, добавить специфичные данные в Header SOAP-сообщения
Итого:
В 90% случаев, использования DataContract будет достаточно для достижения поставленных целей, но если же вам необходимо очень тщательно контролировать "макет" вашего SOAP-сообщения, то тут на помощь приходит MessageContract
Есть класс :
[Serializable]
public class UserAccount
{
public string Name { get; set; }
public string Surname { get; set; }
public string Login { get; set; }
public PasswordBox Password { get; set; }
public UserAccount(string _name, string _surname, string _login, PasswordBox _password)
{
Name = _name;
Surname = _surname;
Login = _login;
Password = _password;
}
}
Метод десериализации:
public void Deserialize()
{
try
{
FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
listUsers = (List
catch
{
listUsers = new List
Ошибка:
Exception thrown: 'System.Windows.Markup.XamlParseException' in
PresentationFramework.dll
Additional information: 'The invocation of the constructor on type 'Gallery.ViewModels.LoginViewModel' that matches the specified
binding constraints threw an exception.' Line number '15' and line
position '10'.
Update
public class LoginViewModel : INotifyPropertyChanged
{
private List
public LoginViewModel()
{
_currentName = String.Empty;
_currentSurname = String.Empty;
_currentLogin = String.Empty;
_currentPasswordBox = new PasswordBox();
Deserialize();
}
private string _currentSurname;
public string CurrentSurname
{
get
{
return _currentSurname;
}
set
{
_currentSurname = value;
OnPropertyChanged();
}
}
private string _currentName;
public string CurrentName
{
get
{
return _currentName;
}
set
{
_currentName = value;
OnPropertyChanged();
}
}
private string _currentLogin;
public string CurrentLogin
{
get
{
return _currentLogin;
}
set
{
_currentLogin = value;
OnPropertyChanged();
}
}
private PasswordBox _currentPasswordBox;
public PasswordBox currentPassword
{
get { return _currentPasswordBox; }
set
{
_currentPasswordBox = value;
OnPropertyChanged();
}
}
private RegistrationCheckCommand checkReg;
public ICommand ButtonClick
{
get { return checkReg ?? (checkReg = new RegistrationCheckCommand(o => AddNewAccount())); }
}
private void AddNewAccount()
{
UserAccount user = new UserAccount(CurrentName, CurrentSurname, CurrentLogin, currentPassword);
listUsers.Add(user);
Serialize();
MessageBox.Show("Account adding!");
}
public void Serialize()
{
try
{
FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, listUsers);
fs.Close();
}
catch
{
}
}
public void Deserialize()
{
//try
//{
FileStream fs = new FileStream("..\\..\\Accounts.dat", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
listUsers = (List
//catch
//{
// listUsers = new List
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Xaml
StackTrace
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler
handler, __BinaryParser serParser, Boolean fCheck, Boolean
isCrossAppDomain, IMethodCallMessage methodCallMessage)
at
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
serializationStream, HeaderHandler handler, Boolean fCheck, Boolean
isCrossAppDomain, IMethodCallMessage methodCallMessage)
at
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
serializationStream)
at Gallery.ViewModels.LoginViewModel.Deserialize() in
C:\Users\Константин\Documents\Visual Studio
2015\Projects\Gallery\Gallery\ViewModels\LoginViewModel.cs:line
121
Замените тип данного свойства
public PasswordBox Password { get; set; }
на string или любой другой тип, не являющийся коллекцией и помеченный как сериализуемый.
PasswordBox - контрол, контролы не сериализуются с помощью стандартных сериализоторов, т.к. являются рекурсивной коллекцией, т.е. любой контрол содержит коллекцию дочерних котролов, пустую или нет - неважно.
После изменений, удалите файл данных, повторите сериализацию и десериализацию.
С ограничениями может быть использован специальный сериализатор либо ручная сериализация.
На данный вопрос уже ответили:
TypeError при изменении списка оператором += внутри кортежа
1 ответ
>>> a = ([],)
>>> a[0].append('pochemy')
>>> a[0] += 'tak'
Traceback (most recent call last):
File "
Почему во втором случае выдается ошибка? Ведь +=, в данном случае, изменяет сам объект, а не создает новый.
Потому что код:
a[0] += 'tak'
эквивалентен:
x = a[0]
x = x.__iadd__('tak')
a[0] = x
Вторая строчка нормально выполняется, изменяя список, но на третьей вылетает исключение, поскольку мы пытаемся изменить кортеж.
Update: вот хорошее подробное объяснение https://ru.stackoverflow.com/a/482925/178077
Я пользуюсь linux. В папке с main.cpp у меня лежат inc_Abc.h и libAbc.so. Всё это я собираю командой:
g++ -o main main.cpp -L. -lAbc
Потом запускаю ./main, но появляется ошибка:
./main: error while loading shared libraries: libAbc.so:
cannot open shared object file: No such file or directory
Почему main не видит libAbc.so, который находится в той же папке?
Я знаю, что этот вопрос можно решить, сделав папку с main -- папкой поиска *.so файлов, с помощью ldconfig. Нельзя ли как-то по-другому это решить?
для разработки или тестирования вполне подойдёт использование переменной окружения LD_LIBRARY_PATH. она может содержать разделённые двоеточием пути для поиска библиотек. текущий каталог, как и обычно, можно обозначить точкой
можно передавать переменную непосредственно при вызове программы:
$ LD_LIBRARY_PATH=. ./main
или экспортировать в текущем экземпляре оболочки:
$ export LD_LIBRARY_PATH=.
тогда в этом экземпляре оболочки можно запускать вашу программу и так:
$ ./main
Есть число 75.4500000, которое получаю при помощи LocationManager(GPS координаты). LocationManager получает координаты и преобразовывает данное значение в 75.45, т.е. обрезает нули, а нужно получать точную цифру.
Как сделать так, чтобы оно не обрезалось, а показывалось полностью?
Если Вы отображаете в TextView, просто используйте String.format
textView.setText(String.format("%.7f",d));
d - Ваш double.
Пишу работу по деревьям в теории графов и немного запутался в понятиях. Мне нужно написать, какие существуют виды деревьев или классификацию деревьев. Я нашел что существует: ориентированное/неориентированное дерево, остовное, лес, бинарное, n-мерное, упорядоченное дерево. Но это всё больше похоже на свойства деревьев нежели на виды (кроме бинарного и n-мерного).
Что из этого (если я правильно нашел и ничего не пропустил) действительно будет являться отдельным видом дерева? Также, есть например частный случай бинарного дерева - дерево поиска. Будет ли такое дерево относиться к теории графов или это больше структура данных в программировании? Тот же вопрос с деревом синтаксического анализа. И последний вопрос: относится ли обход дерева к операциям с деревьями как графами или это алгоритм для структуры данных - дерево?
Раз вы пишите какую-то работу на тему деревьев, то лучше как можно более полно изложить материал.
Часть того, что вы перечислили - общие понятия для графов, часть - понятия для деревьев.
Я бы на вашем месте сделал классификацию по признакам:
По направленности - ориентированное (однонаправленное, двунаправленное), неориентированное
По степени вершины (бинарное, n-арное, и т.п.)
По частным случаям - тоже неплохо описать было бы, чего как. Дерево бинарного поиска можно вложить в классификацию по степеням вершины и описать чем оно выделяется. Дерево синтаксического анализа более специфичная вещь, но если сможете описать - отлично.
Поскольку дерево является графом, то к нему применимы классические алгоритмы обхода любого графа, но помимо этого существуют специфичные алгоритмы именно для деревьев.
Если вы студент, и это какая-то работа для университета, то чем больше вы напишете, при условии что разобрались в сути происходящего - тем лучше. Писать что-то не разобравшись не нужно, может вылезти боком потом.
Прочитал в руководстве MDN о том, как получить из ответа сервера текст, но не очень понял, почему это объект Promise, ведь ответ уже получен, почему нельзя сразу прочитать его?
Например, почему вместо
response.text().then(function(text) {
// ...
});
нельзя было бы сделать:
var text = response.text();
Не знаю, как у них внутри это работает, могу предположить 2 варианта:
Это сделано для унификации интерфейсов, чтоб везде были промисы.
Возможно при вызове fetch только хедеры читаются, а не сам body, только потом при вызове text() начинается чтение самого тела запроса. Плюс в момент вызова text(), вероятно, только начинается чтение. То есть, если бы это было синхронно, как вы предлагаете response.text(), то это заблочило бы основной поток, а так response.text().then(...) сработает только когда файл будет прочитан целиком.
Поправьте, если не прав.
Здравствуйте,код сервлета:
package arver;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by 35717 on 30.03.2016.
*/
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
PrintWriter out = resp.getWriter();
out.print("servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
Файл web.xml
структура папок:
ответ сервера:
HTTP Status 405 - HTTP method GET is not supported by this URL
type Status report
message HTTP method GET is not supported by this URL
description The specified HTTP method is not allowed for the requested
resource.
Apache Tomcat/9.0.0.M4
Может кому поможет:
in your doGet() method, get rid of
super.doGet(req, resp);
The HttpServlet basically follows the template method pattern where all non-overridden HTTP methods returns a HTTP 405 error "Method not supported". When you override such a method, you should not call super method, because you would otherwise still get the HTTP 405 error. The same story goes on for your doPost() method.
Добрый день.
Если используем аннотации, к примеру, для класса.
У нас есть некий абстрактный класс А. У него есть предок, класс B.
И там и там есть аннотация @MyAnnotation. В аннотации есть поле
String[] value() default {};
В итоге получили примерно такое:
@MyAnnotation({"str1","str2"})
abstract class A {}
@MyAnnotation({"str3","str4"})
class B extends A {}
Вопрос: Будут ли суммироваться все значения из класса и суперкласса, или просто возьмется значение из текущего объекта B. Либо, может, еще какие хитрости есть в аннотациях?
Наследование аннотаций возможно при использовании аннотации @Inherited. В вашем случае произойдет просто перекрытие.
Аннотации
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotation {
String name();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotation {
String name();
}
Тестовые классы
@InheritedAnnotation(name = "A1")
public class A1 {}
@InheritedAnnotation(name = "B1")
public class B1 extends A1 {}
public class C1 extends A1 {}
@UninheritedAnnotation(name = "A2")
public class A2 {}
@UninheritedAnnotation(name = "B2")
public class B2 extends A2 {}
public class C2 extends A2 {}
Тест
@Test
public void test() throws Exception {
System.out.println(new A1().getClass().getAnnotation(InheritedAnnotation.class));
System.out.println(new B1().getClass().getAnnotation(InheritedAnnotation.class));
System.out.println(new C1().getClass().getAnnotation(InheritedAnnotation.class));
System.out.println(new A2().getClass().getAnnotation(UninheritedAnnotation.class));
System.out.println(new B2().getClass().getAnnotation(UninheritedAnnotation.class));
System.out.println(new C2().getClass().getAnnotation(UninheritedAnnotation.class));
}
Вывод
//@org.example.InheritedAnnotation(name=A1)
//@org.example.InheritedAnnotation(name=B1)
//@org.example.InheritedAnnotation(name=A1)
//@org.example.UninheritedAnnotation(name=A2)
//@org.example.UninheritedAnnotation(name=B2)
//null
Делаю простенькую игрушку. Логика заключается в том, что у левого края экрана стоит объект, назовем его человеком для удобства. У правого края хаотичным образом спавнятся другие объекты, для удобства, назовем их зомби. Человек убивает их из постоянно стреляющего автомата, "пули" которого при пересечении с "зомби" должны удалять "зомби" с экрана.
Проблема заключается в том, что эти "пули" просто пролетают мимо "зомби". То-есть, я не могу отследить пересечения рендеров "пуль" и "зомби".
Как я понял, проблема в многочисленном объявлении Rectangle-ов "зомби" и "пуль", что приводит к неразберихе в коде и той проблеме, что у меня, в частности. Есть ли возможность объявить его только 1 раз и потом всюду использовать? Если да, то как?
Кстати, просто объявить его на уровне на уровне класса, как тот же Rectangle человека не получается, ибо вылетает NullPointerException, со ссылкой на spawncrowd и spavbullet. Заранее спасибо_)
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.math.Rectangle;
import java.util.Iterator;
public class MyGdxGame extends ApplicationAdapter {
OrthographicCamera camera;
SpriteBatch batch;
Texture manImage, bulletImage, CrowdImage;
Rectangle manRect;
Vector3 touchPos;
Array
long lastbultime, lastcrowdeltime;
int counter_miss;
@Override
public void create () {
camera = new OrthographicCamera();
camera.setToOrtho(false, 960, 540);
touchPos = new Vector3();
batch = new SpriteBatch();
manImage = new Texture("man.jpg");
bulletImage = new Texture("bullet.jpg");
CrowdImage = new Texture("Crowd.jpg");
manRect = new Rectangle();
manRect.x = 0;
manRect.y = 540/2;
manRect.height = 256;
manRect.width = 256;
CrowdElemArray = new Array
public void spawncrowdel() {
Rectangle CrowdelementRect = new Rectangle();
CrowdelementRect.y = MathUtils.random(0, 540-256);
CrowdelementRect.x = 960;
CrowdelementRect.height = 256;
CrowdelementRect.width = 64;
CrowdElemArray.add(CrowdelementRect);
lastcrowdeltime = TimeUtils.nanoTime();
}
public void spawnbullet() {
Rectangle bulletRect = new Rectangle();
bulletRect.y = manRect.getY() + manRect.height/2;
bulletRect.x = manRect.getX();
bulletRect.height = 256;
bulletRect.width = 64;
bulletsArray.add(bulletRect);
lastbultime = TimeUtils.nanoTime();
}
@Override
public void render () {
Gdx.gl.glClearColor(0, 1, 0.5f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(manImage, manRect.x, manRect.y);
for (Rectangle CrowdelementRect: CrowdElemArray) batch.draw(CrowdImage, CrowdelementRect.x, CrowdelementRect.y);
for (Rectangle bulletRect: bulletsArray) batch.draw(bulletImage, bulletRect.x, bulletRect.y);
batch.end();
// Сенсорное урправление
if (Gdx.input.isTouched()){
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
manRect.y = (int) (touchPos.y - 128/2);
}
if (Gdx.input.isKeyPressed(Input.Keys.UP)) manRect.y += 200 * Gdx.graphics.getDeltaTime();
if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) manRect.y -= 200 * Gdx.graphics.getDeltaTime();
if (manRect.y < 0) manRect.y = 0;
if (manRect.y > 540-256) manRect.y = 540-256;
//TODO Спавнинг зомби
if (TimeUtils.nanoTime() - lastcrowdeltime > 2000000000) spawncrowdel();
//TODO Спавнинг пули
if (TimeUtils.nanoTime() - lastbultime > 800000000) spawnbullet();
//TODO Движение зомби
Iterator
//TODO Движение пули
Iterator
}
`
PS
Делал все по шаблону со "стартандроида".
Решение взято отсюда. Человек решает аналогичную задачу через следующий код:
private void testCollision() {
Iterator
if ((Math.abs(balls.x - enemies.x) <= (balls.width + enemies.width) / 2f)
&& (Math.abs(balls.y - enemies.y) <= (balls.height + enemies.height) / 2f)) {
i.remove();
b.remove();
}
}
}
}
когда-то пробовал сам - у меня работало.