Страницы

Поиск по вопросам

суббота, 16 марта 2019 г.

Как работает sync?

Не могу понять как он работает. Есть пример:
#include #include void file_abc() { std::ofstream f("test.txt"); f << "abc
"; } void file_123() { std::ofstream f("test.txt"); f << "123
"; } int main() { file_abc(); // file now contains "abc" std::ifstream f("test.txt"); std::cout << "Reading from the file
"; char c; f >> c; std::cout << c; file_123(); // file now contains "123" f >> c; std::cout << c; f >> c; std::cout << c << '
'; f.close();
file_abc(); // file now contains "abc" f.open("test.txt"); std::cout << "Reading from the file, with sync()
"; f >> c; std::cout << c; file_123(); // file now contains "123" std::cout << f.sync() << std::endl; f >> c; std::cout << c; f >> c; std::cout << c << '
'; }
и вывод должен быть вроде как :
Reading from the file abc Reading from the file, with sync() a23
Но у меня получается
Reading from the file abc Reading from the file abc
При этом f.sync() выдает 0. Как все таки это работает?


Ответ

В вашем примере параллельного чтения и записи в один файл функция sync не спасёт, так как операционка не будет блокировать и синхронизировать бесконечный поток открытия файлов. После открытия файла на чтение все клиенты будут читать одно и то-же из буфера. При изменении файла следующие клиенты будут читать файл из буфера второго и тоже удивляться, что бабка Рая говорила другое. Результат чтения исходников и переводов. Функция sync обновляет буфер чтения до упора памяти. Если буфер заполнен полностью и ничего не добавилось всё остаётся точно так-же. Если файл изменился, то заново буфер обновлятся не будет. Если у вас было желание обновить содержимое буфера, то этот буфер нужно обнулить. Это можно достичь с помощью f.seekg(f.tellg());. Более красивого способа не нашёл.

Как использовать (запускать) class в цикле

Внесу некоторые изменения в вопрос, опишу поподробнее....
Коллеги, есть такой вот пример. В котором я создаю class CreateBlockInfo. не думаю что надо объяснять, что именно происходит в данном классе.
let info = document.querySelectorAll('.info'); class CreateBlockInfo { constructor(elem) { this.fragment = document.createDocumentFragment(); this.element = document.createElement(elem); } Append(parent) { this.fragment.appendChild(this.element); parent.appendChild(this.fragment) } } //Потом создаю экземпляр класса runCreateBlockInfo let runCreateBlockInfo = new CreateBlockInfo('span'); // и вот далее я пытаюсь запустить экземпляр класса в цикле // я хочу в каждый элемент info вставить созданный span for (let i = 0; i < info.length; i++) { runCreateBlockInfo.Append(info[i]); } // рузультат такой, только в последний элемент info вставляется span console.log(info[0].childNodes); console.log(info[1].childNodes); console.log(info[2].childNodes);


Я прекрасно понимаю, что если в цикл создавать новый объект
for (let i = 0; i < info.length; i++) { let runCreateBlockInfo = new CreateBlockInfo(); runCreateBlockInfo.Append(info[i]); }
То я получу, то чего хочу.
Но, тут есть одно НО... Простите за выражение, нутром чую, что это не верно. Так как я создаю один и тот же Объект несколько раз. А мне кажется, что надо один раз проинициализировать новый объект. А потом использовать его сколько душе угодно.
Коллеги, вопрос - верно ли мои умозаключения выше и если да, как выйти из ситуации???
Или может я не верное рассуждаю? Помогите разобраться.


Ответ

Метод .appendChild не создает новый элемент. Если элемент уже есть на странице, то он перенесется из одного места, в другое.
Чтобы решить это, можно создавать элемент span каждый раз, либо клонировать тот, который создан в конструкторе, например:
let info = document.querySelectorAll('.info'); class CreateBlockInfo { constructor(elem) { this.fragment = document.createDocumentFragment(); this.element = document.createElement(elem); } Append(parent) { this.fragment.appendChild(this.element.cloneNode()); parent.appendChild(this.fragment) } } //Потом создаю экземпляр класса runCreateBlockInfo let runCreateBlockInfo = new CreateBlockInfo('span'); // и вот далее я пытаюсь запустить экземпляр класса в цикле // я хочу в каждый элемент info вставить созданный span for (let i = 0; i < info.length; i++) { runCreateBlockInfo.Append(info[i]); } // рузультат такой, только в последний элемент info вставляется span console.log(info[0].childNodes); console.log(info[1].childNodes); console.log(info[2].childNodes); span::before { content: "span" }


Преобразование JSON в URL текст

В поисках решения вот этой проблемы выяснил, что проблема в API, оно принимает не JSON, а в отправляемых данных должен быть URL text. Вопрос такой, можно ли преобразовать такой JSON:
JSONFORMDATA = {
"add": [ { "source_name": "WEB сайт", "source_uid": "a1fee7c0fc436088e64ba2e8822ba2b3", "created_at": "1529007000", "incoming_entities": { "leads": [ { "name": "Покупка" } ], "contacts": [ { "name": "Федя", "responsible_user_id": "1903006", "custom_fields": [ { "id": "382707", "values": [ { "value": "+77777777777", "enum": "WORK" } ] }, { "id": "389993", "values": [ { "value": "sfgh3gh233h3h3h3" } ] }, { "id": "389995", "values": [ { "value": "Обратный звонок" } ] } ] } ] }, "incoming_lead_info": { "form_id": "329248", "form_page": "vdtest.ru", "ip": "127.0.0.1", "service_code": "QkKwSam8" } } ]
}
в такой формат:
add[0][source_name]=WEB FORM &add[0][source_uid]=wb0123456789 &add[0][created_at]=1529105760 &add[0][incoming_entities][leads][0][name]=WEB Bay &add[0][incoming_entities][contacts][0][name]=John &add[0][incoming_entities][contacts][0][responsible_user_id]=2473552 &add[0][incoming_entities][contacts][0][custom_fields][0][id]=382707 &add[0][incoming_entities][contacts][0][custom_fields][0][values][0][value]=+792887776655 &add[0][incoming_entities][contacts][0][custom_fields][0][values][0][enum]=MOB &add[0][incoming_entities][contacts][0][custom_fields][1][id]=389993 &add[0][incoming_entities][contacts][0][custom_fields][1][values][0][value]=cid123456789 &add[0][incoming_entities][contacts][0][custom_fields][2][id]=389995 &add[0][incoming_entities][contacts][0][custom_fields][2][values][0][value]=Product &add[0][incoming_lead_info][form_id]=329248 &add[0][incoming_lead_info][form_page]=localhost &add[0][incoming_lead_info][ip]=127.0.0.1 &add[0][incoming_lead_info][service_code]=myformmw
Это декодированные данные из URL text, которые принимает API:
add%5B0%5D%5Bsource_name%5D=WEB+FORM&add%5B0%5D%5Bsource_uid%5D=wb0123456789&add%5B0%5D%5Bcreated_at%5D=1529105760&add%5B0%5D%5Bincoming_entities%5D%5Bleads%5D%5B0%5D%5Bname%5D=WEB+Bay&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bname%5D=John&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bresponsible_user_id%5D=2473552&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bid%5D=382707&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=%2B792887776655&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bvalues%5D%5B0%5D%5Benum%5D=MOB&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bid%5D=389993&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=cid123456789&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B2%5D%5Bid%5D=389995&add%5B0%5D%5Bincoming_entities%5D%5Bcontacts%5D%5B0%5D%5Bcustom_fields%5D%5B2%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=Product&add%5B0%5D%5Bincoming_lead_info%5D%5Bform_id%5D=329248&add%5B0%5D%5Bincoming_lead_info%5D%5Bform_page%5D=localhost&add%5B0%5D%5Bincoming_lead_info%5D%5Bip%5D=127.0.0.1&add%5B0%5D%5Bincoming_lead_info%5D%5Bservice_code%5D=myformmw
Как выяснилось, в примере PHP не используют чистый JSON, а строят массив. Может в Python тоже необходимо построить подобный массив или есть способ проще, ведь на сколько я понимаю, как таковых массивов в Python нет.


Ответ

Честно, рекурсию не очень люблю, но в таких задачах она себя хорошо показывает:
Данные (из вопроса):
JSON_FORM_DATA = { "add": [ ... }
Код:
def dict_to_url_params(json_data, root): def deep(node, root, items): if isinstance(node, list): for i, value in enumerate(node): node_root = root + '[{}]'.format(i) deep(value, node_root, items)
elif isinstance(node, dict): for key, value in node.items(): node_root = root + '[{}]'.format(key) deep(value, node_root, items)
else: root += '=' + node items.append(root)
items = []
deep(json_data, root, items)
return items
if __name__ == '__main__': items = dict_to_url_params(JSON_FORM_DATA['add'], root='add')
params = '&'.join(items) print('Params: ' + params) print()
print('Params:') for x in items: print(x)
Результат:
Params: add[0][source_name]=WEB сайт&add[0][source_uid]=a1fee7c0fc436088e64ba2e8822ba2b3&add[0][created_at]=1529007000&add[0][incoming_entities][leads][0][name]=Покупка&add[0][incoming_entities][contacts][0][name]=Федя&add[0][incoming_entities][contacts][0][responsible_user_id]=1903006&add[0][incoming_entities][contacts][0][custom_fields][0][id]=382707&add[0][incoming_entities][contacts][0][custom_fields][0][values][0][value]=+77777777777&add[0][incoming_entities][contacts][0][custom_fields][0][values][0][enum]=WORK&add[0][incoming_entities][contacts][0][custom_fields][1][id]=389993&add[0][incoming_entities][contacts][0][custom_fields][1][values][0][value]=sfgh3gh233h3h3h3&add[0][incoming_entities][contacts][0][custom_fields][2][id]=389995&add[0][incoming_entities][contacts][0][custom_fields][2][values][0][value]=Обратный звонок&add[0][incoming_lead_info][form_id]=329248&add[0][incoming_lead_info][form_page]=vdtest.ru&add[0][incoming_lead_info][ip]=127.0.0.1&add[0][incoming_lead_info][service_code]=QkKwSam8
Params: add[0][source_name]=WEB сайт add[0][source_uid]=a1fee7c0fc436088e64ba2e8822ba2b3 add[0][created_at]=1529007000 add[0][incoming_entities][leads][0][name]=Покупка add[0][incoming_entities][contacts][0][name]=Федя add[0][incoming_entities][contacts][0][responsible_user_id]=1903006 add[0][incoming_entities][contacts][0][custom_fields][0][id]=382707 add[0][incoming_entities][contacts][0][custom_fields][0][values][0][value]=+77777777777 add[0][incoming_entities][contacts][0][custom_fields][0][values][0][enum]=WORK add[0][incoming_entities][contacts][0][custom_fields][1][id]=389993 add[0][incoming_entities][contacts][0][custom_fields][1][values][0][value]=sfgh3gh233h3h3h3 add[0][incoming_entities][contacts][0][custom_fields][2][id]=389995 add[0][incoming_entities][contacts][0][custom_fields][2][values][0][value]=Обратный звонок add[0][incoming_lead_info][form_id]=329248 add[0][incoming_lead_info][form_page]=vdtest.ru add[0][incoming_lead_info][ip]=127.0.0.1 add[0][incoming_lead_info][service_code]=QkKwSam8

Configure: передача параметра и значение параметра по умолчанию

Необходимо, чтобы в файле configure.ac была переменная "XXX". При этом, необходимо, чтобы у нее было значение по умолчанию и возможность установить значение, при вызове ./configure. Т.е., чтобы можно было сделать что-то такое: если вызывается ./configure используется значение XXX по умолчанию (пусть будет "ааа") если вызывается ./configure XXX="bbb" значение XXX становится "bbb" Никак не пойму, как для этого необходимо описать файл configure.ac


Ответ

FOO=${FOO:-foo} AC_DEFINE_UNQUOTED([FOO_MACRO],[$FOO],["Desriprion"])
Судя по всему всё что не раскрывается макросом из configure.ac просто поадает в скрипт ./configure. Поэтому для установки переменных можно использовать обычный синтаксис POSIX sh
Можно также задавать значение прямо в макросе, хотя в этом случае есть свои подводные камни с интерпретацией кавычек.
AC_DEFINE_UNQUOTED([FOO_MACRO],[${FOO:-foo}],["Desriprion"])
Также ИМХО хорошим тоном будет объявить эту переменную AC_ARG_VAR

Отсутствуют AccountController и папка Account во Views при использовании Identity

При создании проекта ASP.NET Core(2.1) Web Application => MVC Не нахожу в архитектуре AccountController и папки Account во Views. Авторизацию сделал, проходит, но внести изменения в оформление и функционал страниц логина не могу, так как не нахожу их в проекте. Подскажите, где их найти, или как вносить изменения?


Ответ

Начиная с Asp.Net Core 2.1, Identity вынесена в отдельную либу (Razor Class Library), поэтому нет ни контроллеров, ни представлений.
Чтобы кастомизировать Identity, нужно использовать Scaffolder - он позволяет выборочно добавлять исходный код нужных компонентов в проект, чтобы его можно было править.
Вот, как это сделать:
From Solution Explorer, right-click on the project > Add > New Scaffolded Item (Создать шаблонный элемент). From the left pane of the Add Scaffold dialog, select Identity(Удостоверение) > Add In the Add Identity dialog, select the options you want.
Подробности в документации

Отображение огромного количества символов

Пишу проект на Vue.js и возник вопрос отображения огромного количества текста. Как выяснилось даже пустой документ содержащий более миллиона символов начинает сильно тормозить при выделении либо редактировании его. Есть ли какие либо способы предотвратить это? Вариант при котором текст отображается частями к сожалению не подходит(


Ответ

как отображать книги на сайте ?
вариант первый - книга имеет формат .txt
в этом случае обычно файл считывается и помещается
в одну переменную в массив строк , которые, к стати говоря, уже проще отображать частями. разделение книги в этом случае происходит, например, по абзацам (/

/g)
частями или весь текст отображать
Вариант при котором текст отображается частями к сожалению не подходит(
дайте пользователю возможность решить самому
преимущества отображения целиком
не нужно писать поиск по книге (ctrl+f есть в каждом браузере) т.к. весь текст в одной переменной легче написать свой способ выделения (например с помощью перетаскивания флажков)
недостатки отображения целиком
возможны тормоза при отображении целиком нет навигации нет картинок нет стилистического оформления ...
вариант альтернативный - использовать книги в формате .fb2
fb2 "FictionBook" переводится как "Художественная книга". fb2 - очень популярный, открытый формат хранения книг (описание формата FB2 от Sclex). поддерживается большим количеством читалок, в том числе и электронных. есть читалки, написанные на JS, например:
плагин для firefox этот же плагин на github

Анимация слайдера HTML CSS

Помогите, пожалуйста. Есть сухой слайдер на чистом CSS и JS, как сделать чтобы была хоть какая-то плавная анимация? Заранее спасибо
var slideIndex = 1; showDivs(slideIndex); function plusDivs(n) { showDivs(slideIndex += n); } function showDivs(n) { var i; var x = document.getElementsByClassName("mySlides"); if (n > x.length) {slideIndex = 1} if (n < 1) {slideIndex = x.length} for (i = 0; i < x.length; i++) { x[i].style.display = "none"; } x[slideIndex-1].style.display = "flex"; } .slider { display: -webkit-box; display: -ms-flexbox; display: flex; margin-top: 100px; -webkit-box-align: center; -ms-flex-align: center; align-items: center; padding-bottom: 100px; } .slider i { font-size: 40px; cursor: pointer; color: #2df3ab; } .slider i[onclick="plusDivs(-1)"] { padding-right: 30px; } .slider i[onclick="plusDivs(1)"] { padding-left: 30px; } .slider .mySlides { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; background-color: #050505; -webkit-box-shadow: 2px 2px 8px rgba(45, 243, 171, 0.15); box-shadow: 2px 2px 8px rgba(45, 243, 171, 0.15); border-radius: 20px; -webkit-box-align: center; -ms-flex-align: center; align-items: center; padding: 35px 30px 35px 30px; } .slider .mySlides .card-desc { padding-left: 60px; } .slider .mySlides .card-desc h1 { color: #ffffff; font-size: 36px; font-weight: 700; line-height: 50px; text-transform: uppercase; } .slider .mySlides .card-desc p { color: #f2f2f2; font-size: 16px; font-weight: 400; line-height: 25px; margin-top: 30px; } .slider .mySlides .card-desc button { color: #ffffff; width: 374px; height: 65px; font-size: 24px; font-weight: 500; line-height: 20.7px; text-transform: uppercase; -webkit-box-shadow: 0 3px 10px rgba(255, 255, 255, 0.75); box-shadow: 0 3px 10px rgba(255, 255, 255, 0.75); border: none; outline: none; cursor: pointer; border-radius: 33px; background-image: -webkit-gradient(linear, left bottom, left top, from(#bc24fb), to(#1d6bff)); background-image: linear-gradient(to top, #bc24fb 0%, #1d6bff 100%); }

Фото карты

Название дизайна карты

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.

Фото карты

Название дизайна карты

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.

Фото карты

Название дизайна карты

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.



Ответ

Если хотите анимацию, вам нужно отказаться от display: none
Вместо этого задайте слайдам абсолютное позиционирование и opacity:0, а активному слайду задавайте opacity:1
Ну и transition: .3s для плавного перехода из прозрачности
Единственная проблема, нужно явно задать размеры родителя, ибо слайды будут абсолютно спозиционированы, но в принципе все слайдера работают именно так
Высоту самого большого слайда можно определить скриптом и задать эту высоту родителю

delay на смену заголовка

Пожалуй, это глупый вопрос, но почему-то не получается разобраться. Есть такая интересная маленькая и хрупкая библиотека i miss you: https://github.com/Bahlaouane-Hamza/I-Miss-You (github). Суть в том, что когда мы уходим со вкладки, заголовок меняется на какой мы захотим, например, на i miss you, а так же можно поменять иконку до тех пор, пока пользователь не вернеться.
Нахожу навязчивым ставить такое в обычный режим, поэтому хотел бы сделать delay хотя бы в 30 минут, но не получается это сделать таким образом, каким умею я.

Спасите неваляшку! Умоляю!


Ответ

Судя по тому, что к этому плагину нет никакой документации, в нём нет возможность сделать то, что вы хотите. Единственный выход - открыть исходных код плагина и переписать его.
Поставить задержку на $.iMissYou(); не выйдет, т.к. слушатель на смену вкладки навешивается самим плагином...
Можно попробовать обойтись без плагина, смену тайтла можно сделать как-то так :

А если с задержкой, то как-то так:
timerId = null;
function func1() { document.title='документ неактивен' }
function func2() { document.title='документ снова активен' }
window.onblur = function () { clearTimeout(timerId); timerId = setTimeout(func1, 30000); } window.onfocus = function () { clearTimeout(timerId); func2(); }
Сменить фавикон можно как-то так (не уверен что сработает, сам не пробовал):

$("#favicon").attr("href","icon2.png");
Фавиконки обычно жестко кешируются, нужно пробовать...

Обращение к ползунку инпута range на js

Нужен был слайдер для выбора цвета. Нашёл решение и немного изменил: https://codepen.io/hobuttt/pen/zLoyWx Проблема в следующем: ползунок должен окрашиваться в выбранный цвет. В найденном варианте используется:
if (typeof InstallTrigger !== 'undefined') { var stylesheet = document.styleSheets[0]; stylesheet.insertRule('input[type=range]::-moz-range-thumb { background: ' + bkgColor + ' }', stylesheet.cssRules.length); } else { document.styleSheets[0].addRule('input[type=range]::-webkit-slider-thumb', 'background-color: ' + bkgColor); }
Но в реале это не работает :
Обращение через querySelector тоже не срабатывает. Есть у кого-то варианты, как это можно решить?


Ответ

Не вижу проблемы, код рабочий. При необходимости, добавьте правила для IE. Учтите также, что во всех браузерах, кроме префиксов, сильно разнится то, как применяются стили. Например, в Хроме border расположен внутри ползунка, а в Мозилле снаружи.
// safari needs window.onload window.onload = function() { // create a element to hold the color gradient var canvas = document.createElement('canvas'); // range is 208-40=168, add 1 so range value stays inside the canvas canvas.width = 169; canvas.height = 1; // create a 2d context var canvasContext = canvas.getContext("2d"); // create linear gradient specify x,y,width,height var gradient = canvasContext.createLinearGradient(0, 0, canvas.width, canvas.height); // define colors to add - can use any color format but must be in quotes gradient.addColorStop(0, "#ff0000"); gradient.addColorStop(.17, "#ff00ff"); gradient.addColorStop(.33, "#0000ff"); gradient.addColorStop(.50, "#00ffff"); gradient.addColorStop(.67, "#00ff00"); gradient.addColorStop(.83, "#ffff00"); gradient.addColorStop(1, "#ff0000"); // use the gradient as a fill canvasContext.fillStyle = gradient; // draw the fill onto the canvas, specify x,y,width,height canvasContext.fillRect(0, 0, canvas.width, canvas.height); var thumb = document.getElementById("slider"); // updates the thumb colors while you drag the thumb, not sure why 'drag' event didn't work here thumb.addEventListener('mousemove', function() { changeColors(); }); // if 'mousemove' is too fast sometimes value and color won't // match up with thumb position, so update just in case thumb.addEventListener('change', function() { changeColors(); }); // display initial value var circle = document.getElementById("circle"); circle.innerHTML = thumb.value; // amount to increment/decrement // google's metronome uses 2, 3, and 4 steps var steps = 2; // decrement when minus is clicked var minus = document.getElementById("minus"); minus.addEventListener('click', function() { thumb.value = Number(thumb.value) - steps; changeColors(); }); // increment when plus is clicked var plus = document.getElementById("plus"); plus.addEventListener('click', function() { thumb.value = Number(thumb.value) + steps; changeColors(); }); // run it once to set colors changeColors(); // set the rgb values from using x, y coordinates function changeColors() { //range starts at 40 so subtract 40 var xCoord = thumb.value - 40; // get the color data from the canvas var rgbValues = canvas.getContext('2d').getImageData(xCoord, 0, 1, 1).data; var bkgColor = "rgb(" + rgbValues[0] + ", " + rgbValues[1] + ", " + rgbValues[2] + ")"; // display thumb value circle.innerHTML = thumb.value; // set colors circle.style.backgroundColor = bkgColor; minus.style.color = bkgColor; plus.style.color = bkgColor; // dynamically change color of thumb pseudo-element by adding new styles // test for Firefox API or else thumb won't change colors var stylesheet = document.styleSheets[0]; if (typeof InstallTrigger !== 'undefined') { stylesheet.insertRule('input[type=range]::-moz-range-thumb { border-color: ' + bkgColor + ' }', stylesheet.cssRules.length); } else { stylesheet.addRule('input[type=range]::-webkit-slider-thumb', 'border-color: ' + bkgColor); } } } #circle { width: 100px; height: 100px; border-radius: 50%; color: #FFF; font-weight: bold; font-family: sans-serif; font-size: 30px; text-align: center; line-height: 100px; } #slider { width: 420px; } #minus, #plus { font-weight: bold; font-size: 30px; cursor: pointer; -webkit-user-select: none; /* Chrome/Safari/Opera */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ } #slider { -webkit-appearance: none; -moz-appearance: none; outline: none; } #slider::-webkit-slider-runnable-track { width: 300px; height: 4px; background: linear-gradient(to left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); border: none; border-radius: 3px; margin-top: -15px; } #slider::-moz-range-track { width: 420px; height: 4px; background: linear-gradient(to left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); border: none; border-radius: 3px; margin-top: -15px; } #slider::-webkit-slider-thumb { -webkit-appearance: none; background: #fff; border-width: 4px; border-style: solid; height: 20px; width: 20px; border-radius: 50%; margin-top: -8px; } #slider::-moz-range-thumb { -moz-appearance: none; background: #fff; border-width: 4px; border-style: solid; height: 12px; width: 12px; border-radius: 50%; margin-top: -8px } canvas { border: solid 1px #f00; display: block; margin: 20px 0; }

+

Ещё было замечено (в версиях браузеров более ранних, чем актуальные), что при стилизации нативных элементов, лучше использовать не общие свойства (например, border: width style color;), а разбивать на отдельные (border-width: ... и т.д.)

вопросов по выводу данных

есть в таблице
ENUM '0','1',...,'30'
Каждое число, имеет свое название. Есть ли более компактный вывод, нежели
if ($a->b==0) $b = 'название0';
и тд. как-то убого оно смотрится.


Ответ

Обычно для этого используются массивы
$data = [ 0 => 'name0', 1 => 'name1', ........ 30 => 'name30' ]; $b = $data[$a->b];
Или в БД заводится таблица классификатор
Names id | name ----------- 0 | 'name0' 1 | 'name1' ........ 30 | 'name30'
И все выборки делаются с джойном этой таблицы

Как происходит расчет физики и отрисовка графики в разных потоках?

Решил дописать игрушку: Есть 4 фигуры который двигаются по экрану. например метод figure.update() перерасчитывает координаты фигуры. И есть пятая фигура, которой я управляю посредством касания к сенсору. Переопределенный метод onTouchEvent(MotionEvent event) считывает данные с сенсора и обновляет координаты мной управляемой фигуры. Теперь как идет отрисовка: выполнил figure.update() для всех фигур, нарисовал. А вот управляемая мной фигура тоже рисуется на втором шаге, но изменение ее координат происходит в зависимости от касаний сенсора. Т.е. может возникнуть ситуация , что в момент когда я рисую, обновились координаты фигуры, X уже обновлен, а переменная Y еще не обновлена. В итоге отрисуется не совсем верное положение фигуры. Возможно на 60 fps эти косяки не заметны..я лично не вижу никаких таких ошибок, когда запускаю игру, как будто всё точно рассчитывается. Но ведь по логике ошибки должны быть..Разве не должна возникнуть такая ошибка: что идет отрисовка, а у этой фигуры координата в этот момент обновляется сенсором, ведь работа от сенсора идет в UI потоке, а весь остальной расчет физики и отрисовки в доп. потоке. Выходит я должен эти переменные пометить как синхронизированные, но даже без этой пометки никаких исключений нет.
Я бы привел код, но думаю он тут лишний, еще раз повторюсь: В UI потоке изменяется значение фигуры в зависимости от результатов сенсора, а в доп. потоке идет отрисовка этой фигуры. Почему нет исключений, вызванных тем, что на отрисовку нужна координата, которая в данный момент изменяется в UI потоке. Или же почему не заметно на глаз таких вот моментов, что координата X изменилась при резком движении по сенсору , а Y еще имеет старое значение. Мне в голову приходит такой ответ: UI потоку всего то надо от сенсора полученные две переменные обновить и справляется с этим он быстро. Доп. поток имеет всегда обе координаты считанные от одного и того же считывания сенсора. Но вопрос остается такой: если UI часто обновляется координаты (я быстро вожу пальцем по экрану), то почему доп. поток не нарывается на ситуация, когда координата занята записью из UI потока.


Ответ

Используются объекты синхронизации и поочередный расчет физики, отрисовки и ввода от пользователя. Как вы верно заметили, одновременно работать с данными из нескольких потоков просто так нельзя.
К примеру, вы делаете расчет физики 50 раз в секунду (чаще не имеет смысла, т.к. на экране вы не увидите более 100 кадров в сек и поймете что что-то движется не идеально). Каждый тик физики вы можете смотреть изменилось ли что-то, пришли ли новые команды от игрока, и примените их. Команды игрока обычно буферизируются и обрабатываются между физикой и отрисовкой. То есть ваша программа будет работать примерно так:
Ф О О О В Ф О О В Ф О О О В Ф О О // Ф-физика, О-отрисовка, В-ввод от игрока
Физика и команды обрабатываются с фиксированным шагом, отрисовка - сколько успеет. Для плавности картинки - используйте интерполяцию (или экстраполяцию).
Пролет через другие тела решается на стороне обработчика коллизий (проверяйте не только точки на коллизию, но и полный путь между ними).

Какие технологии необходимо знать для реализации

Какие технологии необходимо изучить чтоб реализовать нечто подобное - проект на дрибл
Я умею верстать обычные сайты с обычными анимациями, но у меня нет даже примерного концепта реализации для чего-то подобного. Сначала я подумал это можно сделать с помощью canvas но как реализовать shape morphing с canvas? Возможно есть какие-то ресурсы на англ\русском где можно прочитать или посмотреть реализацию подобных анимаций


Ответ

Для создания подобного сайта вам не потребуется canvas. На этом сайте используется конечно же HTML и CSS, Javascript и Jquery. Вам потребуется также знание SVG для создания того синего желейного элемента(читайте про animate в SVG). Никакой canvas здесь не требуется.

Удалить и снова добавить текст в DIV

как удалить из div ранее добавленный текст, и записать новый если он есть?
Календарь

Пн Вт Ср Чт Пт Сб Вс
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31


Ответ

Воспользуйся методом который перезапишет все содержимое, а не будет менять существующее, к примеру .text()
$( ".polucit" ).on("click", function() { const data = []; // создай массив для значений
$(".colored").each(function (i, elem) { data.push( $(elem).text() ); // собери все значения циклом });
$(".vivod").text(data.join(", ")); // перезапиши вывод });

Как работать с svn через HTTP прокси на Ubuntu?

При попытке извлечения кода svn выдает следующую ошибку:
svn: OPTIONS of 'http://...': Не удалось разрешить имя хоста `...': Host not found (http://...)


Ответ

Нужно прописать параметры прокси в настройках svn. sudo nano /etc/subversion/servers [global] http-proxy-host = defaultproxy.whatever.com http-proxy-port = 7000

Ant - создание Jar с библиотеками внутри

Что хочется сделать с помощью Apache Ant: Создать 1 jar файл Внутри него такая структура /lib/ <- сюда складываем все библиотеки /META-INF/ <- здесь указываем Main-Class /com/... <- скомпилированные классы /тут файлы-конфиги Возможно ли так сделать, если да, то как сложить все библиотеки которые находятся в разных папках в папку lib + при вызове java -jar name.jar эти библиотеки оказывали в classpath этого jar-ника Спасибо. Сделал так, но он складывает все классы в рут jar-ника (вместе с папками)


Ответ

Насколько я понимаю у вас два вопроса:
как сложить jar-ники в папку lib/ внутри другого jar. Это достигается при помощи аттрибута prefix у zipfileset как сделать так, чтобы при запуске java -jar name.jar то что в lib попадало в classpath. Этого можно достичь при помощи one jar, если не хочется возиться, причем тогда первая часть вопроса отпадает сама собой, или вручную при помощи Jar class loader

Получение представления для сочетания клавиш

Допустим, у меня в приложении есть контрол, имеющий какой-либо KeyStroke. И у него автоматически выставляется ToolTip в зависимости от системы. Например, на Windows это текст вида Ctrl+Shift+Z, а на MacOS - ⌘⇧Z. Как получить эту строку для заданного сочетания клавиш? P.S. Интересует получение данной строки как с помощью AWT (или Swing).


Ответ

Смотрие в сторону KeyEvent.getKeyModifiersText, KeyEvent.getKeyText и KeyEvent.getKeyModifiersExText

Поиск по ListBox

Ребята, подскажите поиск по ЛистБоксу. Необходимо, чтобы в Edit вписывалось слово и, если такое словое есть, то игнорировать, а если нету, то добавить в ListBox. Буду очень признателен за любую помощь.


Ответ

Не знаю как в старых версиях, но в последней Delphi XE2 регистр при сравнении не учитывается. Поэтому такой код работает без проблем: if ListBox1.Items.IndexOf(Edit1.Text) < 0 then ListBox1.Items.Add(Edit1.Text);

Custom Arc Drawable ProgressBar

Необходимо сделать плавно заполняющийся ProgressBar следующего вида:
Есть ресурсы background.png

progress.png

Пробовал делать так main.xml

back_arc.xml

Результат получился немного не такой.


Ответ

C помощью стандартного ProgressBar заявленную штуку не получилось сделать. Результат был достигнут с помощью RelativeLayout и наложением картинок друг на друга - снизу progress.png затем фон, который с помощью Rotate двигался в виде "заслонки" и поверх фон с дыркой под дугу (расписал, может кому-нибудь и пригодится).

Как создать ярлык на рабочем столе?

Хотелось бы узнать, можно ли средствами Java, создавать ярлыки на рабочем столе?Т.е. нажал кнопку - создался ярлык.


Ответ

Нашёл вариант создания ярлыка, вдруг кому-то тоже пригодится.

Организация передачи потокового видео с веб-камеры на C# (mono)

Задача: между двумя локальными машинами под управлением linux внутри локальной TCP/IP сети необходимо организовать видео-трансляцию используя возможности C# фреймворка Mono. Для захвата видео можно использовать библиотеку OpenCV. Подскажите куда копать?


Ответ

Для .net существует отличная библиотека компьютерного зрения AForge, в которой, кроме всего прочего, есть работа с web-камерами. Кстати, эта библиотека - не обертка над OpenCV. Как эта библиотека работает с Mono, не могу подсказать, к сожалению.
http://www.aforgenet.com/

Как получить сведения о процессоре?

Здравствуйте! Как можно с помощью ассемблерных вставок получить сведения о процессоре? Дополнено. Вот нашел команду cpuid и код: mov ЕАХ,О cpuid ;EAX=0001h mov mem, ЕВХ mov mem+4, EDX mov mem+8, ECX ;mem='Genuinelntel' cpuid EAX=543h (например) ,EDX = lBFh Но как это сделать вставкой на том же C?


Ответ

Инструкция cpuid предназначена для получения информации о процессоре. Для некоторых компиляторов она доступна как расширение языка __cpuid. Пример использования int main() { int a, b;
for (a = 0; a < 3; a++) { __asm("cpuid":"=a"(b) // EAX - в b (вывод) : "a"(a) // a - в EAX (ввод) : "%ebx", "%ecx", "%edx"); // cpuid всегда задействует их
printf("Этот код %i дает %i
", a, b); }
return 0; }

Рекурсия в регулярных выражениях

Здравствуйте. Есть регулярное выражение (для примера) / \( ( [^)(]+ | (?R) )+ \) /x (?R) означает рекурсивную ссылку на само регулярное выражение, где можно найти обработчик регулярных выражений, поддерживающих такие рекурсии для Java или Python ? Стандартные java.util.regex и питоновский regex кажется не имеют поддержки этого механизма. Регулярное выражение взято здесь


Ответ

https://pypi.python.org/pypi/regex Альтернативный движок для регулярных выражений питона с поддержкой рекурсий. Java движка кажется не существует в настоящее время.

Deserialize вариационных (типизированных) XML

Раньше не сталкивался с сериализацией объектов, особенно с сериализацией в XML и обратно, но пришлось - да не знаю как быть с объектами в которых присутствует поле класса Object, в котором могут быть объекты нескольких типов. Пример XML 123 1001 232 1001 943 TheName Пример XML Error Message Предполагаю, что классы можно записать так (хотя в записи не уверен, ибо не работает): [XmlRootAttribute("Entities", Namespace = "http://site.org/", IsNullable = false)] public class BoxPackages { [XmlArray(IsNullable = true)] public BoxError Error; [XmlArray(IsNullable = true)] public object[] Package; }
public class BoxError { public String Message; }
[XmlRootAttribute("TypeA")] public class PackageTypeA { public Int32 ID; public Int64 Number; }
[XmlRootAttribute("TypeB")] public class PackageTypeB { public Int32 ID; public Byte Type; }
[XmlRootAttribute("TypeC")] public class PackageTypeC { public Int32 ID; public String Name; } Понятно, что классов не достаточно - нужна ещё какая-то настройка сериализатора. Кто знает, как настроить сериализатор (XmlAttributes из коробки) для десериализации XML в объект типа BoxPackages? Подскажите, пожалуйста?


Ответ

Класс XmlSerializer умеет сериализовать только известные типы. Т.к. в массве object[] может быть любой объект любого типа, в конструкторе этого класса надо перечислить все возможные типы объектов, которые предполагается использовать: Type [] extraTypes = new Type[3]; extraTypes[0] = typeof(PackageTypeA); extraTypes[1] = typeof(PackageTypeB); extraTypes[2] = typeof(PackageTypeC);
// Create the XmlSerializer instance. XmlSerializer mySerializer = new XmlSerializer(typeof(BoxPackages),extraTypes); Этот пример основан на XmlSerializer - конструктор

Будет ли CUDA код работать на других видеокартах?

Будет ли программа, использующая технологию CUDA работать в системах на видеокартах NVidia, не поддерживающих CUDA ? А в системах на видеокартах других производителей?


Ответ

Смотря как написана программа. В норме - не будет.

shared data в Qt

Здравствуйте. У меня возникли небольшие непонимания концепции shared data в Qt. Я прочел соотв. раздел в книги Макса Шлее, а затем ещё одну статью на сайте нокии, где об этом говорилось, но до конца не понял. Я понял, что при простом присваивании классов происходит то же, что и в C#,Java - копируются только ссылки, но указывают они на одни данные. Однако (исходя из книги), если произвести изменения над одним из объектов, то для измененного объекта создается отдельная копия, а счетчик ссылок на старые данные уменьшится на один. Но разве это хорошая концепция? Ведь получается, что это неэффективно. Каждый раз, когда я буду модифицировать данные - будет создаваться новая копия, а старая уничтожаться? Или же копия создается только тогда, когда 2 объекта указывают на одну память? А если, к примеру, у меня есть объект, и есть ещё несколько объектов, в которые я заношу копии объекта первого, затем они где-то, к примеру, у меня модифицируются все. И, к примеру, этих модификаций много и мне не нужно, чтобы в том блоке, где они модифицируются, происходило много копирований памяти, мне нужно, чтобы они заранее скопировались, что тогда делать? Также я встретил там такую фразу: ... вызов конструктора копирования или оператора присваивания не приведет к копированию данных, а только увеличит счетчик ссылок на эти данные на 1 Т.е. конструктор копирования не имеет смысла писать? Его тело не будет выполнятся? Или оно будет выполняться, но не тогда, когда я его вызвал явно, а когда происходит тот самый момент, что один из объектов, указывающих на одну область памяти, модифицирует свои данные? Спасибо.


Ответ

Рекомендую почитать копирование при записи (там про ОС, но на русском, смысл тот же), copy-on-write (на английском, но есть примеры на C++). Если будут вопросы - пишите еще. Если коротко, то копия объекта будет создаваться только тогда, когда происходит изменение данных. Если мы добавляем ссылку на созданный объект, то увеличивается внутренний счетчик. Если мы удаляем объект (который ссылается на какой-либо общий ресурс (shared memory), то внутренний счетчик уменьшается на 1 и если он станет равным 0, произойдет удаление объекта (очистка shared memory).

Поиск точек для многомерной сферы

Можно ли расширить данную задачу до N-мерного случая?
Даже так: является ли использование рекурсии и переменного числа аргументов здесь оправданным?
что-то типа
function get_dimension($point,$radius,$dimension_axis){ for($i=floor($point[$dimension_axis]-$radius);$i<=ceil($point[$dimension_axis]+$r);$i++){ if($dimension_axis>count($point)){ //Операции с мегамерным массивом }else{ get_dimension($point,$radius,++$dimension_axis); } }


Ответ

По идее, обобщить легко, и рекурсия (по количеству измерений) мне кажется подходящим инструментом. Я бы сделал как-то так (не тестировал и на псевдокоде, извините, не спец по php): process_points(int currdim, point currpoint, point center, double radius) { var r2 = radius * radius; var currpointR2 = 0; for (var dim = 0; dim < currdim - 1; dim++) currpointR2 += (currpoint[dim] - center[dim]) * (currpoint[dim] - center[dim]); var restR2 = r2 - currpointR2; if (restR2 < 0) return; var restR = sqrt(restR2); var min = floor(center[currdim] - restR); var max = ceil(center[currdim] + restR); for (var xx = min; xx <= max; xx++) { point newCurrPoint = currpoint; newCurrPoint[dim] = xx; if (currdim < totaldims - 1) process_points(currdim + 1, newCurrPoint, center, radius); else // last dim paint_point(newCurrPoint); } }
process_points(0, center, center, r);

Отладка лямбда-функций

Скажите, есть ли в Visual Studio какие-то возможности выполнять отладку кода, содержащего лямбда-функции? Отладчик при попытках прогнать через него такой кодругается благим матом. Может, имеются какие-то соответствующие расширения для студии?


Ответ

Здесь приведены возможные варианты отладки: Фильтрация коллекций в отладочных окнах Visual Studio

Как прикрепить патч для dll к проекту?

Я написал приложение на SDL + OPENGL + C++ в CodeBlocks. Обнаружил, что при запуске исполняемого файла, скомпилированного в релизе (при запуске в релизе в самой среде всё отлично работает) приложение некоторые .png файлы не загружает (а именно png-24) и выдаёт в файл для ошибок (stderr) "libpng warning: Interlace handling should be turned on when using png_ read_ image". Как выяснилось, sdl_ image использует такую libpng(а именно libpng15-15.dll, другие я пробовал, sdl_image вроде требует именно эту либу), в которой функция png_read_image имеет ошибку. Я долго искал решение (png-24 нужны), качал вроде бы более новые версии libpng, но всё тщетно. Нашёл патч, который должен фиксить эту ошибку: --- libpng-1.5.0/pngread.c.ark 2011-01-14 12:27:23.440018507 +0100 +++ libpng-1.5.0/pngread.c 2011-01-14 12:28:02.866685173 +0100 @@ -841,7 +841,7 @@ png_read_image(png_structp png_ptr, png_ } else { - if (!(png_ptr->transformations & PNG_INTERLACE)) + if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) { /* Caller called png_start_read_image or png_read_update_info without * first turning on the PNG_INTERLACE transform. We can fix this here, но не пойму? как его прицепить к проекту. Скомпилировать свою libpng из исходников пока не получается (очень не хочется этим заниматься). Помогите пожалуйста!


Ответ

Итак, нашёлся ответ. Собственно я нашёл решение только по другим странностям, когда релиз и дебаг версии начали работать совсем не так, как скомпилированные .ехе. начали вылетать ошибки на простейших функциях opengl и сам .ехе вариант очень тормозил. Оказывается я в начале сунул какую-то кривую версию библиотеки opengl в папку и компилятор работал с нормальной, а вот ехе с кривой.

Запуск приложений на Qt 5.0.1 на других компьютерах

На моем рабочем компьютере стоит Qt 5.0.1 (MinGW сборка), собираю проект, кидаю все нужные либы в папку, запускаю - работает. Убрал из настроек переменных окружения специально, что бы убедиться, что все чисто, все пути связанные с Qt, все равно работает. При запуске же на любом другом компьютере, на котором не стоит Qt SDK, вылетает рантайм эррор, причем на разных разный, где то с указанием пути к запускаемому экзешнику, где то просто с телом ошибки. MS Visual C++ Redistributable стоят, даже переустанавливал специально вручную - безрезультатно. В чем может быть проблема? Как это можно исправить? Может ли это быть какой либо косяк самой оффициальной сборки Qt, скачанной с сайта http://qt-project.org/downloads ?


Ответ

@KoVadim , спасибо огромное! Скачал утилиту Process Monitor по ссылке, которую вы дали, запустил свое приложение на компе, на котором оно не работает, потом запустил эту утилиту, сделал фильтр по имени моего приложения, и увидел кучу запросов к различным dll и ресурсам реестра, в итоге нашел один путь с пометкой , и взял с машины с установленным Qt SDK эту папку со всем вложенным содержимым и закинул с полным сохранением имени на машину с проблемой запуска приложения. Папка эта - c:\Qt\Qt5.0.1\5.0.1\mingw47_32. Запустил приложение и, о чудо, оно заработало! В итоге методом последовательного исключения удалил все ненужное из этой папки (в ней было вложено8 папок с либами). Оказалась нужной только одна - platforms. потом эту папку просто переместил в папку с моим приложением и все продолжиоло работать. Ну еще удалил из этой папки дебаг версии библиотек (те, что оканчиваются на *d.dll) и все.

Определение количества пикселей определенного цвета на луче из центра координат

Декартова система координат. Черно белое изображение. Центр находиться самостоятельно, основываясь на данных по общей площади изображения (центр тяжести).
Далее из центра нужно проводить лучи под углами от 0 до 360 с заданным шагом (например, 5 градусов). И для каждого луча, считать количество черных пикселей на нем.
Как пробовал считать я. Луч брал за гипотенузу, и через тангенс угла - находил противолежащий катет. Проделывал эту операцию для каждого пикселя по оси Х, и на пересечении координат пикселей Х и величины катета - проверял черный пиксель или нет.
Но данные какие то слишком неточные. Для изображения буквы "К" я получил почти одинаковые значения количества пикселей на всех лучах. Подозреваю, что я считаю не правильно. Делаю это на C# .NET.
Сама задача академическая. В чем суть. Строиться гистограмма, которая показывает отношение количества пикселей к углу луча. Для изображений символов, эти гистограммы субъективно похожи. Грубо говоря, для одного символа разных шрифтов - гистограммы будут схожи.
Координаты центра тяжести находятся по формулам.
Для координаты Х
Для координаты Y
Функция A(). Значение равно 1 - если пиксель черный, 0 - если белый.
Посоветуйте что-то или подскажите решение.


Ответ

Посмотрите картинку

Ваши лучи наложенные на пиксельную сетку дают большую погрешность. Судя по всему, дело именно в этом.
Вот еще хорошая картинка, на которой видно что как лучи пересекают пиксели.

Не правильная работа анимации CSS3

Приветствую!
Решил попробовать написать часы с помощью CSS3 трансформаций, но столкнулся с проблемой слишком медленной анимацией.
Например я задаю анимацию секундной стрелки, которая за 1 минуту должна повернуться на 360 градусов, но вместо минуты она поворачивается немного медленнее и из за этого часы начинают "отставать". В чем может быть проблема и как ее можно решить?
Код тут: jsfiddle
HTML


CSS
.clock { border: 1px solid; width: 300px; height: 300px; border-radius: 100%; position: relative; }
.hour { height: 40%; width: 5px; background: red; position: absolute; left: 50%; top: 10%; margin-left: -3px; -webkit-transform-origin: 50% 100%; -webkit-animation: hour 43200s linear infinite; }
.minute { height: 46%; width: 3px; background: green; position: absolute; left: 50%; top: 5%; margin-left: -2px; -webkit-transform-origin: 50% 100%; -webkit-animation: min 3600s linear infinite; }
.secunde { height: 50%; width: 3px; background: #ccc; position: absolute; left: 50%; margin-left: -2px; -webkit-transform-origin: 50% 100%; -webkit-animation: sec 59s linear infinite; }
@-webkit-keyframes sec { from { -webkit-transform: rotate(252deg); }
to { -webkit-transform: rotate(360deg); }; }
@-webkit-keyframes min { from { -webkit-transform: rotate(72deg); }
to { -webkit-transform: rotate(360deg); }; }
@-webkit-keyframes hour { from { -webkit-transform: rotate(360deg); }
to { -webkit-transform: rotate(360deg); }; }
#js-clock { width: 300px; height: 300px; border: 1px solid; border-radius: 100%; }


Ответ

Из-за времени выполнения скрипта и других причин ориентироваться на счётчик не правильно. Как вариант предлагаю несколько путей решения: Использовать меньшее время задержки, чтобы учесть отставание. Реализовать часы с помощью js с проверкой времени на сервере.

Порядок выполнения функций

Есть GameObject. В нем 2 компонента: MainLevelSetting и RespawnController. Классе MainLevelSetting: void Start () { Debug.Log( "Start MainLevelSetting" ); GetComponent().RespawnHero(); } И в RespawnController: void Start () { Debug.Log( "Start RespawnController" ); }
public void RespawnHero(){ Debug.Log( "RespawnHero" ); } Поле запуска, в консоле отоброжается: "Start MainLevelSetting" "RespawnHero" "Start RespawnController" То есть сначала вызывается метод класса, а потом только метод инициализируется! Где ошибка и как исправить?


Ответ

Нашел статью про порядок событий http://habrahabr.ru/post/147315/ и понял что я заблуждался! Start вызывается не при инициализации класс( я думал что это аналог конструктора из С++ ), а До первого обновления кадров Start: вызывается перед прорисовкой первого фрейма, только если сценарий определён. А (может не совсем правильно выражусь) аналог является функция: Первая загрузка сцены Эти функции вызываются, когда сцена стартует (по одному разу для каждого объекта в кадре). Awake: Эта функция всегда вызывается до начала любых функций, а также сразу после инициализации префаба. То есть то что нужно!! Но для моего случая больше подошло переделать методы. Так что думаю ответ на вопрос найден! =)

Неявное поведение поля NSManagedObject'а

Имею некий NSManagedObject-обьект названный, скажем Object. У него есть поле info типа NSString. По логике программы я должен иметь возможность сохранить в это поле пустое значение, то есть строку нулевой длины. При сохранении я так и поступаю. Но когда я фетчу данный обьект из Core Dat'ы и логирую значение этого поля оно уже равно (null). Если была сохранена строка ненулевой длины то она отдается корректно. Если это ошибка то не понимаю на каком этапе я могу ее допустить. В целях теста присваиваю значение полю, делаю save контексту и сразу тут же его фетчу. Получаю такой результат. Чем может быть обусловлено такое поведение?


Ответ

Ах, как я люблю вопросы, в которых (без бутылки) без research effort'а сразу и не разобраться. Если серьёзно, то мои тесты не подтверждают то, что вы говорите: ниже я привожу два тестовых сценария (у меня они оба выполняются). User - это просто тестовая entity, которая имеет поле name типа string с включенной (это дефолт у Xcode) опцией "optional" (то есть оно необязательное, то есть может быть nil'ом), я полагаю, что у вас на вашем текстовом поле optional тоже включено. Так вот первый сценарий - это мы приравниваем name тестового пользователя к пустой строке @"", сохраняем контекст и фетчим его заново. И убеждаемся, что поле таки является пустой строкой. Второй сценарий - это мы заведомо приравниваем name к nil и закономерно убеждаемся после фетча, что name - это nil Вывод из всего этого такой: похоже вы сохраняете не строку, а nil. Некоторое время назад я создал на Github специальный репозиторий для того, чтобы изучать разные тонкости устройства Cocoa. Для этого я просто прописываю подробные тесты для соответствующих аспектов поведения Core Data или NS-объектов, которые хочу изучить. Ваш случай я только что расположил здесь см. CoreData_Integration. Если будет желание освоить такой Test-Driven способ изучения тонкостей Cocoa, можно постучаться ко мне в скайп, и я объясню, как это работает, так как инструкции по эксплуатации проекта пока что нет. describe(@"Behavior of string-NSString fields", ^{ context(@"When a string field is set to empty string", ^{ it(@"should return its value as an empty string (not nil!)", ^{ User *user = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([User class]) inManagedObjectContext:managedObjectContext()];
user.name = @"";
[managedObjectContext() save:nil];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];
NSError *error; NSArray *fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:&error];
if (error) { NSLog(@"Error %@", error); }
user = (User *)[fetchResult lastObject];
[[user.name should] equal:@""]; }); });
context(@"When a string field is set to nil", ^{ it(@"should return its value as nil", ^{ User *user = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([User class]) inManagedObjectContext:managedObjectContext()];
user.name = nil;
[managedObjectContext() save:nil];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];
NSError *error; NSArray *fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:&error];
if (error) { NSLog(@"Error %@", error); }
user = (User *)[fetchResult lastObject];
[[user.name should] beNil]; }); }); });

Сортировка английских и русских слов в NSArray

Нужно отсортировать массив так, чтобы сначала шли слова на Русском, а только потом на Английском. Пробовал разные compare функции localizedCompare: localizedCaseInsensitiveCompare: localizedStandardCompare: и compare:options:range:locale: , не помогло. Подскажите пожалуйста, кто сталкивался Пример: @[Abc, Bcd, Абв, Def, Бвг]; - входящий массив @[Абв, Бвг, Abc, Bcd, Def]; - то что нужно получить


Ответ

Если массив содержит только русские и английские слова, то можно создать 2 вспомогательные строки с английским и русским алфавитом. В сортировке брать первую по индексу букву из слова, приводить к нижнему регистру(если не нужно сортировать слова с большой и маленькой буквы), узнавать к какому языку она принадлежит и сравнивать слова между собой если они одного языка.
Вот так:
NSArray* words = @[@"Abc",@"Bcd",@"Grf",@"Влд",@"Гдр",@"Жзн",@"Hbr",@"Абв",@"Def",@"Бвг",@"Cdf",@"Acf",@"Aba"];
NSString* englishChar = @"abcdefghijklmnopqrstuvwxyz";
NSString* russianChar = @"абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
NSArray* sortWords = [words sortedArrayUsingComparator:^NSComparisonResult(NSString* obj1, NSString* obj2) {
NSString* prefixObj1 = [[obj1 lowercaseString] substringToIndex:1];
NSString* prefixObj2 = [[obj2 lowercaseString] substringToIndex:1];
if ([englishChar containsString:prefixObj1]) {
if ([englishChar containsString:prefixObj2]) { return [obj1 compare: obj2]; } else { return 1; }
} else if ([russianChar containsString:prefixObj1]) {
if ([russianChar containsString:prefixObj2]) { return [obj1 compare: obj2]; } else { return 0; }
}
return [obj1 compare: obj2]; }];

Анимация на iOS7 не работает (на iOS6 все ОК)

С переходом на Xcode 5 и iOS7 SDK получил проблему при адаптации приложения под новую ось. Типичный код анимации перемещаения отказывается работать. На устройствах со старой iOS все нормально, а на новой анимация не визуализируется: [UIView animateWithDuration:0.5 animations:^(void){ self.ItemPhoto.alpha = 0; } completion:^(BOOL finished) { self.ItemPhoto.frame = CGRectMake(70, 20, self.ItemPhoto.frame.size.width,self.ItemPhoto.frame.size.height);
self.ItemPhoto.alpha=1; }]; По факту картинка меняет свою позицию, но без анимации


Ответ

Попробуйте сделать вот так: self.ItemPhoto.alpha = 0; // Откуда вы начинаете анимацию
[UIView animateWithDuration:0.5 animations:^(void){ // А это куда вы хотите прийти в течение 0.5 секунд self.ItemPhoto.frame = CGRectMake(70, 20, self.ItemPhoto.frame.size.width, self.ItemPhoto.frame.size.height); self.ItemPhoto.alpha=1; } completion:^(BOOL finished) { // А это запускается __после__ того, как 0.5 секунд прошли }]; Надеюсь, я правильно понял логику вашей анимации.

Как наилучшим образом “смержить” два JSONObject?

Имеем: JSONObject o1 = { "one": "1", "two": "2", "three": "3" } JSONObject o2 = { "four": "4", "five": "5", "six": "6" } В результате слияния o1 и o2 должны получить: JSONObject result = { "one": "1", "two": "2", "three": "3", "four": "4", "five": "5", "six": "6" } Один из вариантов - использвать иторатор по keys, и пока hasNext - добавлять поле по ключу в новый объект. Ищу более красивый способ. Note - Ключи в o1 и o2 повторяться не могут.


Ответ

Я пришел к тому, что наилучшим решением будет использования иторатора jsonObject.keys() и ручной сборки результурующего объекта. public JSONObject mergeJsonObjects(JSONObject o1, JSONObject o2) { JSONObject result = new JSONObject(); Iterator i1 = o1.keys(); Iterator i2 = o2.keys(); String tmp_key; while (i1.hasNext()) { tmp_key = (String) i1.next(); try { result.put(tmp_key, o1.get(tmp_key)); }catch (JSONException ignored){} } while (i2.hasNext()) { tmp_key = (String) i2.next(); try { result.put(tmp_key, o2.get(tmp_key)); }catch (JSONException ignored){} } return result; } upd: public JSONObject mergeJsonObjects(ArrayList jsonObjects) { JSONObject result = new JSONObject(); String tmp_key; for (JSONObject jsonObject: jsonObjects){ Iterator iterator = jsonObject.keys(); while (iterator.hasNext()) { tmp_key = (String) iterator.next(); try { result.put(tmp_key, jsonObject.get(tmp_key)); }catch (JSONException ignored){} } } return result; }

ВКонтакте доступ к jQuery из UserJS

Если открыть консоль браузера на странице ВКонтакте, то введя
$
увидим в выводе объект jQuery, но если внедрить на страницу UserScript:
function append() { console.log( $ ); };
window.setInterval( append, 1000 );
то ровно раз в секунду в консоль будет падать ошибка undefined В каком пространстве имен искать jQuery и как вообще такое может быть, ведь UserScript исполняется в глобальном контексте и в том же контексте происходит работа, если напрямую вводить команды в консоль ?


Ответ

Команды из консоли выполняются в контексте window + доступно API самого браузера. То, что вы видите, это ссылка на один из методов API браузера. Подробно с API системой вы можете познакомиться в документации соответствующего браузера. Сам сайт ВКонтакте не использует в своей работе библиотеку jQuery

Как сделать функцию с необязательным параметром в СИ

Имеется функция вида f(p1, *p2, *p3, *p4) { ... } По указателям p3 и p4 присваиваются определённые значения, которые не всегда нужны во внешней программе, т.е. эти аргументы, в отличие от p1 и p2, являются не обязательными. Как можно реализовать на Си, чтобы можно было использовать эту функцию без "возвращения" значений туда, на что указывают p3 и p4? Например, чтобы можно было использовать как f(a1, &a2), так и f(a1, &a2, a3, a4)


Ответ

@Ilyazh, если еще актуально, то вот пример такой функции (из рабочей программы в Linux) static int check_args_nz(void *a, ...) { va_list ap; va_start(ap, a);
int i; for (i = 0; a; i++) a = va_arg(ap, void *);
va_end(ap); return i; } Для теста вызывать можно примерно так: int a = 1; char *b = "abc"; double c;
printf ("%d %d %d
", check_args_nz(0, "2", &a, 0), check_args_nz(&a, b, &b, &c, 0), check_args_nz((void *)a, 0)); результат: $ ./a.out 0 4 1 $

Странный роутинг в kohana3

Приветствую вас. Столкнулся с очень странной проблемой: kohana3, судя по поведению, в нетрезвом состоянии, так как при правильно заданном маршруте для роутера выскакивает ошибочка: Kohana_HTTP_Exception [ 404 ]: The requested URL signup was not found on this server. Маршрут написан по мануалу в точности. Route::set('assest', '', array( 'action' => '(login|signup|logout)' )) ->defaults(array( 'controller' => 'Assest' )); .htaccess стандартный, изменения не вносились. Вот такие вот странности, знает кто, как лечить это?


Ответ

Снова моя не внимательность, не обратил внимание на строчку из документации, так как она написано очень мелким шрифтом, которая гласит, что маршрут должен быть задан до стандартного :D

Работа с Git и человеком, который им не пользуется

Добрый день! Ситуация такая: есть проект, который лежит на удаленном сервере, я все изменения вношу на локальной машине, потом при помощи Git отправляю изменения на сервер, есть дизайнер, который не умеет работать с Git и вносит правки на продакшене. Мне приходится лезть на сервер добавлять все правки дизайнера в репозиторий, а потом пулить (pull) изменения в свою локальную версию проекта. Хочется перестать сливать изменения дизайнера на продакшене, а делать это на своей локальной машине, а потом все одим махом отправлять на удаленный сервер. Есть ли в Git какой-нибудь инструмент, с помощью которого можно пулить незафиксированные изменения? Может быть, есть какой другой способ работы в команде в такой ситуации? Заранее спасибо за Ваш ответ/совет. P.S. Ответ капитана: Научить дизайнера использовать Git.


Ответ

Если он ещё и верстальщик (а может, и фронтенд разработчик), то без гита тяжело, настройте ему .ssh ключ чтобы не требовалось вводить никаких паролей и научите такой команде: git add . && git commit -am 'frontend development' && git pull origin master && git push origin master - объясните что это будет что-то типа "сохранить свои изменения и вылить". В консоле гита ему достаточно будет набрать "вверх" и "enter" и всё. :) Если про "батник", то смысл в следующем: найти папку, куда установлен гит, у меня это C:\Program Files (x86)\Git\bin элемент списка; добавить "переменную среду" (PATH): Панель управления > Система > Дополнительные параметры > Переменные среды > выбираем параметр PATH и дописываем через этот пусть к гиту; создаем файл, например, apply.bat, и прописываем там: git add . && git commit -am 'frontend development' && git pull origin master && git push origin master Не забудьте поменять ветку на свою.

С какого запроса следует начинать авторизацию на DropBox?

Доброго времени суток, уважаемые форумчане!
Изучаю документацию по протоколу Oauth 1.0 для DropBox, но не могу понять, с какого запроса следует начинать сеанс обращения к серверу DropBox. В документации написано, что первый запрос должен содержать следующие параметры:
oauth_consumer_key: The Consumer Key. oauth_signature_method: The signature method the Consumer used to sign the request. oauth_signature: The signature as defined in Signing Requests. oauth_timestamp: As defined in Nonce and Timestamp. oauth_nonce: As defined in Nonce and Timestamp. oauth_version: OPTIONAL. If present, value MUST be 1.0 . Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. Service Providers’ response to non-1.0 value is left undefined. Additional parameters: Any additional parameters, as defined by the Service Provider.
Для вычисления подписи предлагается использовать PLAINTEXT, HMAC-SHA1 или RSA-SHA1. Методом PLAINTEXT ничего не получилось, как не пыталась отправлять запросы, сервер всё время возвращал ошибку "Not authorized".
Решила попробовать создавать подпись с помощью HMAC-SHA1, но не понятно, что будет являться входным параметром, а что ключом. Подскажите ещё, пожалуйста, какой нужно отправлять метод: POST или GET, куда передавать параметры: в строку запроса или в тело запроса?
Ссылка на рефы DropBox: http://oauth.net/core/1.0/#signing_process
Пример:
wstring url = L"https://www.dropbox.com/home/request_token"; wstring oauth_nonce; CreateRequestParam(oauth_nonce); wstring oauth_callback = L""; wstring oauth_consumer_key = L"my App key"; wstring oauth_consumer_secret = L"my App secret"; wstring oauth_signature_method = L"PLAINTEXT"; wstring oauth_timestamp = to_wstring(*(double*)time); wstring oauth_version = L"1.0"; wstring oauth_signature = oauth_consumer_secret + L"&"; wstring params = L"oauth_consumer_key=" + oauth_consumer_key + L"&oauth_signature_method=" + oauth_signature_method + L"&oauth_signature=" + oauth_signature + L"&oauth_timestamp=" + oauth_timestamp + L"&oauth_nonce=" + oauth_nonce + L"&oauth_version=" + oauth_version;
int err = PostRequest(url, params);
На указанный url отправляю HTTP POST запрос, в теле передаю параметры, указанные выше. Должны возвращаться out_token и outh_secret, но возвращается страница в html-формате, в которой нет ни того, ни другого. Что я делаю не так?


Ответ

Не знаю, актуален ли еще вопрос, попробую ответить.
Первый запрос на адрес https://api.dropbox.com/1/oauth/request_token
Пример:
POST https://api.dropbox.com/1/oauth/request_token HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0 Host: api.dropbox.com Accept: */* Accept-Encoding: deflate, gzip Authorization: OAuth oauth_consumer_key="973quph3jxdgqoe",oauth_nonce="105816471209",oauth_signature="wloizpn331cc8zd&",oauth_signature_method="PLAINTEXT",oauth_timestamp="Wed%2C%2013%20May%202015%2015%3A37%3A53%20%2B0000",oauth_version="1.0" Content-Length: 0 Content-Type: application/x-www-form-urlencoded
В ответ получаете oauth_token
HTTP/1.1 200 OK Server: nginx Date: Wed, 13 May 2015 15:46:32 GMT Content-Type: application/x-www-form-urlencoded ... Content-Length: 64
oauth_token_secret=LZl8HyVRQuP1ifON&oauth_token=RS4XReiBykw8WHNz
Затем отправляете пользователя в браузер на страничку https://www.dropbox.com/1/oauth/authorize?oauth_token=RS4XReiBykw8WHNz
Пользователь нажимает кнопочку Allow.
Затем выполняете запрос на второй URL (подписываете его уже с использованием полученного ранее oauth_token_secret
https://api.dropbox.com/1/oauth/access_token
POST https://api.dropbox.com/1/oauth/access_token HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0 Host: api.dropbox.com Accept: */* Accept-Encoding: deflate, gzip Authorization: OAuth oauth_consumer_key="973quph3jxdgqoe",oauth_nonce="847334669",oauth_signature="wloizpn331cc8zd&LZl8HyVRQuP1ifON",oauth_signature_method="PLAINTEXT",oauth_timestamp="Wed%2C%2013%20May%202015%2015%3A46%3A46%20%2B0000",oauth_token="RS4XReiBykw8WHNz",oauth_version="1.0" Content-Length: 0 Content-Type: application/x-www-form-urlencoded
И получаете в ответ токен, который будете использовать при последующих запросах:
HTTP/1.1 200 OK Server: nginx Date: Wed, 13 May 2015 15:46:55 GMT Content-Type: application/x-www-form-urlencoded Connection: keep-alive ... Content-Length: 76
oauth_token_secret=32mdalirxxxxa8j&oauth_token=yx8f9rdxxxxj8dia&uid=1921xxxx
Пример авторизации на Dropbox
Пример OAuth авторизации на Flickr с подписыванием запроса HMAC-SHA1

Зачем нужна константа TYPE внутри классов, определённых в пакете java.lang?

Задаю вопрос исключительно ради "научного" интереса. Используется эта константа для компилятора? Или её можно использовать в коде? Если да, то зачем?
Для ясности о чём идёт речь, полное содержимое файла Void.java:
package java.lang;
/** * The {@code Void} class is an uninstantiable placeholder class to hold a * reference to the {@code Class} object representing the Java keyword * void. * * @author unascribed * @since JDK1.1 */ public final class Void {
/** * The {@code Class} object representing the pseudo-type corresponding to * the keyword {@code void}. */
@SuppressWarnings("unchecked") public static final Class TYPE = (Class) Class.getPrimitiveClass("void");
/* * The Void class cannot be instantiated. */ private Void() {} }


Ответ

Например для того, чтобы убедиться, что найденный вами через рефлекшен метод ничего не возвращает. То есть:
if (Void.TYPE == m.getReturnType())

git subtree внутри одного репозитория

Как слить содержимое папки ветки 1 в ветку 2 и поддерживать синхронность папки в ветке 1 и ветки 2?
Контекст:
Делаю библиотеку, в т.ч. для выкладывания на github.com, на github принято выкладывать master-ветки без файлов проекта и окружения (файл настроек ide, подтянутые зависимости и т.п.), я же привык всё таскать с собой, чтобы легко было восстановить окружение.
Нужно сделать так:
ветка env: моё рабочее окружение, вместе с подтянутыми зависимостями. Чтобы можно было просто сделать checkout и скомпилировать проект.
ветка master - только непосредственно мои исходники.
Речь идет о репизитории https://github.com/rekby/mbr, сейчас туда загружен вариант с веткой env. Ветка master пуста. В master должно быть содержимое https://github.com/rekby/mbr/tree/env/src/github.com/rekby/mbr
По документации я понял что мне хорошо должен подойти вариант поддеревьев (subtree) - я работаю в своей env-ветке и периодически сливаю изменения в мастер. При необходимости из master подтягиваю их обратно через git diff-tree
В этом месте возникла проблема - git diff-tree работает не так как я этого ожидаю.
Например:
git checkout env git diff-tree -R -r -p master src/github.com/rekby/mbr
Как я понимаю должен мне выдать отличия в src/github.com/rekby/mbr ветки env (текущей) и корнем ветки master (в которой и должен оказаться мой код). Вывод команды пуст.
Попробовал с --relative и еще несколько вариантов - результат тот же.


Ответ

посмотреть отличия в файлах, находящихся в разных каталогах в двух разных ветках можно так:
$ git diff branch1:path/num/1 branch2:path/num/2
в вашем конкретном случае примерно так:
$ git diff master: env:src/github.com/rekby/mbr
если достаточно просто перенести изменения в ветку master, то можно, переключившись в эту ветку, выполнить примерно такую команду:
$ git checkout master $ git diff master: env:src/github.com/rekby/mbr | git apply
если же требуется перенести коммиты (т.е., коммит-сообщения, дату, авторство), то тогда следует ориентироваться не на различия в файлах (получаемые с помощью diff-а), а на различия в списке коммитов. придётся как-то самостоятельно отслеживать — какие коммиты уже перенесены, а какие ещё нет (я, к сожалению, не знаю средств git-а, позволяющих автоматизировать такой процесс — с изменением путей).
получить набор patch-файлов, содержащих коммиты, начиная с заданного, в вашем случае можно примерно так:
$ git checkout env $ git format-patch хэш-последнего-уже-перенесённого-коммита $ git checkout master $ git am -p5 *.patch
обратите внимание на параметр -p5 для команды git am. он указывает отбросить 5 элементов в пути файлов, перечисленных в патче, т.е. вместо a/src/github.com/rekby/mbr/mbr.go получится просто mbr.go
не забудьте после этого удалить сформированные файлы *.patch, чтобы не возникло проблем при следующих переносах.
чтобы сформировать patch-файл для одного коммита, можно передать команде git format-patch параметр -1
$ git format-patch -1 хэш-переносимого-коммита

Если приложение удалено, будут ли деньги сниматься за подписку?

Если приложение удалено, будут ли деньги сниматься за подписку? Что-то нигде в доках не могу этого найти.


Ответ

Да.
Когда пользователь попытается удалить приложение, он получит предупреждение, что имеется активная подписка. Если он проигнорирует предупреждение и продолжит удаление, то подписка останется активной.
Соус:
App uninstallation When the user uninstalls an app that includes purchased subscriptions, the Play Store app will notify the user that there are active subscriptions. If the user chooses to continue with the uninstallation, the app is removed and the subscriptions remain active and recurring billing continues. The user can return to cancel the associated subscriptions at any time in the My Apps screen of the Play Store app. If the user chooses to cancel the uninstallation, the app and subscriptions remain as they were. https://developer.android.com/google/play/billing/billing_subscriptions.html

Javascript: коллбэки, асинхронность и разделение кода

Здравствуйте.
Есть cordova приложение. Есть плагин, который я могу вызвать со стороны javascript, чтобы получить данные извне, например, через такой враппер:
CordovaWrapper.getRawData(successCallback, errorCallback);
Данные, которые я получу из cordova (они придут как аргументы successCallback), я бы хотел использовать в HTML приложении.
Конечно, можно во всех местах, где нужны данные из successCallback, использовать этот CordovaWrapper, чтобы получить данные и сразу же использовать:
CordovaWrapper.getRawData(function(JSONString) { var data = JSON.parse(JSONString) for (var i in data) { data[i].formattedValue = ''+data[i].value+''; }
// здесь мы используем эти полученные и отформатированные данные
}, function(e) { console.log(e) });
Но мне это не кажется хорошей идеей. Кроме того, хорошо бы было закешировать распаршенный JSON с примененным к нему форматированием.
Я мало знаком с Javascript, но мне хотелось бы реализовать какой-нибудь провайдер данных, к которому я смогу обращаться, чтобы получать закешированные и отформатированные данные из cordova (используя этот гипотетический CordovaWrapper). И в случае работы приложения в браузере, а не на девайсе, отдавать какие-нибудь захардкоженые данные.
if (standaloneMode) { // какие-то тестовые данные return [{ value: 'test1', options: [...], }, { value: 'test2', options: [...], }]; } else { return dataFromCordova; }
Проблема в том, что получение данных - асинхронное.
Если делать асинхронно, получается коллбэк на коллбэке:
Объявление:
DataProvider.getData = function(callback) { var format = function (arr) { for (var i in arr) { arr[i].formattedValue = ''+arr[i].value+''; } return arr; };
if (standaloneMode) { var testData = [{ value: 'test1', options: [...], }, { value: 'test2', options: [...], }];
callback(format(testData)); return; }
if (this.cache) { callback(this.cache); } else { var successCallback = function(JSONString) { data = JSON.parse(JSONString); callback(format(data)); }; CordovaWrapper.getRawData(successCallback, errorCallback); } }
И использование:
DataProvider.getData(function (data) { // здесь мы используем эти полученные и отформатированные данные });
Были мысли загружать данные в провайдер до использования. Но, опять же, нет гарантий, что момент, когда эти данные будут нужны, не наступит раньше, чем эти данные будут получены из cordova.
Как правильно сделать? Нормально ли это, хотеть отдельный класс/объект, который будет предоставлять данные? Нормально ли иметь столько коллбэков из-за асинхронности? Как делать такого рода кеширование? Как не дублировать строчки вида
callback(format(data));
?


Ответ

JavaScript это ивентво ориентированный язык, то есть лапша из колбеков это обычное дело. К сожелению текущая версия JavaScript не позволяет упростить работу с колбеками, и для этого вам необходимо подобрать библиотеку для упрощения логики работы с событиями.
Замечу что если у вас в приложении действительно много колбеков то возможно стоит ознакомиться с Функциональным реактивным программированием. Вот очень мотивирующи доклад к изучению FRP.
Но в большинстве случаев FRP будет излишним, и можно воспользоваться Promise (на самом деле это частный случай FRP). Промисы будут достепны в ES6 а пока вы можете воспользоваться реализацией промисов из какой-нибудь библиотеки например jquery
Promise - это специальный объект который выпонит успешный callback или callback с ошибкой и гарантирует что один из этих колбеков будет выполнен и выполнен только один раз. На основании этих условий есть разные средства для комбинирования промисов, например метод when из jquery. Если вам нужно больше вариантов для комбинирования промисов, посмотрите библиотеку Q
По поводу вашего вопроса с кешированием ответа я приведу пример с использованием jquery, в других библотеках решение не должно сильно отличаться.
В jquery есть класс Deferred который помогает создавать промисы.
Вам нужно создать объект Deferred var deferred = new $.Deferred() например в вашем врапере и вернуть промис deferred.promise() В вашем врапере в момент получения данных необходимо вызвать метод resolve если получение данных было успешным или reject в противном случае. У обекта который вы получите в результате метода deferred.promise() будут методы done и fail которые принимают callback. Обратите внимание что колбек вызовится в любом случае, даже если получение данных произошло до добавления колбеков в методы done и fail
Таким образом вы можете создать 1 объект Deferred для каждого запроса в функции получения данных и возвращать промис каждый раз при обрашении к функции. В итоге вы получите кеширование данных и избавитесь от лапшы колбеков.
Примеры Deferred
Статья про промисы

Чтение данных с arduino uno через COM порт

Доброе время суток! Возникла проблема: код на arduino нормально работает, во встроенном мониторе порта данные правильно отображаются. Но в приложении на C#, особенно очень часто в самом начале приходит непонятных мусор вместо значений. Типичные значения во встроенном мониторе:
145 0 145 0
Значения в программе на C#:
SSH(??j - откуда берутся эти строки? 145 143 ??j
Код программы
public partial class MainWindow : Window { SerialPort sp = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
public MainWindow() { InitializeComponent();
sp.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived); sp.Open(); }
private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { Dispatcher.BeginInvoke(new Action(delegate() { this.console.Text += sp.ReadExisting(); }));
}
private void ReadPort(object source, ElapsedEventArgs e) {
}
private void readButton_Click(object sender, RoutedEventArgs e) {
} }
}


Ответ

Много работал с компортом и ардуиной. Тагер(для лезертага) делал и прочее. Как я понял мусор в компорте - это вообще норма. Собственно для этого и существуют различные протоколы передачи данных. В простейшем случае, ты должен сначала слать идентификатор начала данных. Это может быть что угодно. Допустим [StartData]. Следом шлешь данные. А после идентификатор конца данных. [StopData]. Не плохо бы еще прикрутить контрольную сумму(гугли по CRC) и длину данных. Тогда в с# ты будешь сначала искать в потоке компорта идентификатор начала пакета. Потом читать ответ до идентификатора конца пакета.
Реализовывать чтение можно по-байтово. Считываем байт - если равен '[', то читаем дальше, если следующий 'S' то продолжаем. Нет - отбрасываем, начинаем сначала.

Ввод данных с клавиатуры - Rust

Здравствуйте! Как я могу считать данные вводимые пользователем с клавиатуры? Здесь также задан вопрос, но предложенные способы очень неудобны. Можно ли как-то считать строку в стиле Python (input()) или C++/Си (cin/scanf())? А если нет, то как сделать это более удобным способом?
UPD
Нашел это. Подключаю к проекту:
[dependencies.text_io] version = "*" features = ["nightly"]
Но к сожалению уверенно отказывается компилироваться quasi v0.3.0


Ответ

Написал небольшую функцию:
fn read_string(comment:&str) -> String { println!("{}", comment); let mut string: String = String::new();
std::io::stdin().read_line(&mut string) .ok() .expect("Error read line!");
return string; }
Если вместо return string написать return string.trim().parse::().unwrap(); можно получить тип i32, а по аналогии - все остальные. Теперь можно писать так: let number:i32 = read_i32("Input number: "); Пока не знаю, как выполнить чтение на одной строке с желаемым тектом, т.е при использовании примера выше:
Input number: (здесь вводится текст)
UPD
Чтобы текст вводился на одной строке с комментарием к нему модифицируйте функцию:
use std::io::Write; use std::io;
fn read_string(comment:&str) -> String { print!("{}", comment); io::stdout().flush();
let mut string: String = String::new();
io::stdin().read_line(&mut string) .ok() .expect("Error read line!");
return string; }

Объединение объектов в массиве по ключу

У меня имеется массив с разными данными , который выглядит примерно так:
[ { "_id": "556c978be20c7cd0087c6f10", "username": "ivan", "music": [ "Metallica" ] }, { "_id": "556c978be20c7cd0087c6f10", "username": "ivan", "interests": [ "Music", "Djent" ] }, { "_id": "556c978be20c7cd0087c6f13", "username": "alina", "interests": [ "Music", "Literature" ] }, { "_id": "556c978be20c7cd0087c6f13", "username": "alina", "music": [ "Skyharbor" ] } ]
Как с объединить объекты в массиве по ключам ('_id') следующим образом (приоритет lodash):
[ { "_id": "556c978be20c7cd0087c6f10", "username": "ivan", "music": [ "Metallica" ], "interests": [ "Music", "Djent" ] }, { "_id": "556c978be20c7cd0087c6f13", "username": "alina", "music": [ "Skyharbor" ] "interests": [ "Music", "Literature" ] } ]


Ответ

Сгруппировать по идентификаторам можно с помощью groupBy, а затем объединить пары с помощью merge
var users = [{ "_id": "556c978be20c7cd0087c6f10", "username": "ivan", "music": [ "Metallica" ] }, { "_id": "556c978be20c7cd0087c6f10", "username": "ivan", "interests": [ "Music", "Djent" ] }, { "_id": "556c978be20c7cd0087c6f13", "username": "alina", "interests": [ "Music", "Literature" ] }, { "_id": "556c978be20c7cd0087c6f13", "username": "alina", "music": [ "Skyharbor" ] }]; console.log( _.map( _.groupBy( users, function (u) { return u._id } ), function (g) { return _.merge.apply(this, g) } ) );
P. S. Прошу ногами не бить, в первый раз в жизни вижу lodash.

Ошибка SOAP looks like we got no XML document.Как исправить?

Добрый вечер.
Начал разбираться с SOAP,набросал простенький сервис новостей и клиент под него и получил ошибку.
Что есть:
сервис новостей,находится в папке news (все это крутится на OpenServre`e) soap-server,находится в папке news/soap wsdl файл news.wsdl,находится в папке news/soap soap-client,находится в папке localhost
Что я делаю:
Запускаю OpenServer,перехожу на localhost - вылетает
Операция Client вернула ошибку: looks like we got no XML document
Проверил кодировки и BOM-символы,все в порядке.
soap-server.php
setClass("NewsService"); // Запуск сервера $server->handle();
soap-client.php
getNewsCount(); echo "

Всего новостей: $result

"; // Сколько новостей в категории Политика? $result = $client->getNewsCountByCat(1); echo "

Всего новостей в категории Политика:$result

"; // Покажем конкретную новость $result = $client->getNewsById(5); $news = unserialize(base64_decode($result)); var_dump($news); }catch(SoapFault $e){ echo 'Операция '.$e->faultcode.' вернула ошибку: '.$e->getMessage(); }
news.wsdl







Где,я ошибся? Что исправить?
Признателен за уделенное время.


Ответ

Добавте
ob_clean(); ob_start();
Перед
$server->handle();