Lua heeft een garbage collector die zomaar veel tijd kan opsoeperen. Dat wil je NOOIT bij realtime software zoals games.
DAAROM is Squirrel de enige juiste programmeertaal voor realtime toepassingen die je met C/C++ wilt laten samenwerken.
zaterdag 22 december 2018
vrijdag 21 december 2018
NewtonSoft JSON
JToken - abstract base class
JContainer - abstract base class of JTokens that can contain other JTokens
JArray - represents a JSON array (contains an ordered list of JTokens)
JObject - represents a JSON object (contains a collection of JProperties)
JProperty - represents a JSON property (a name/JToken pair inside a JObject)
JValue - represents a primitive JSON value (string, number, boolean, null)
vrijdag 14 december 2018
Ken je Javascript
Ontwikkelaars zijn tegenwoordig veel bezig met Typescript en Angular, allebei lagen bovenop Javascript. Vergeet niet de Javascript en CSS essentials bij te houden.
Ken je bijvoorbeeld alle methods van javascript Object?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
Ken je bijvoorbeeld alle methods van javascript Object?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
zondag 9 december 2018
Powerpoint 2010 video invoegen: QuickTime installeren?
Als je in Powerpoint 2010 een video wilt invoegen (bijvoorbeeld een MP4), dan komt er een dialog dat "QuickTime" geinstalleerd moet worden. Dat klopt niet. Je kunt k-lite video codecs installeren en dan werkt het.
maandag 19 november 2018
Using NuGet.Core PackageDownloader
Using the nuget.core library in C# to download all packages from a nuget repository is difficult. The class PackageDownloader is not handy. I ended up using the WebClient to download the package.
This is the code:
string nugetBase = "http://proget.company.com/nuget/company-repo";
IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(nugetBase);
var query = repo.Search("", true);
string path = "c:\\packages";
WebClient cln = new WebClient();
foreach (DataServicePackage elem in query)
{
string dir = path + "\\" + elem.Id;
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
cln.DownloadFile(elem.DownloadUrl.AbsoluteUri, (path + "\\" + elem.Id + "\\" + elem.Id + "." + elem.Version + ".nupkg"));
}
This is the code:
string nugetBase = "http://proget.company.com/nuget/company-repo";
IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(nugetBase);
var query = repo.Search("", true);
string path = "c:\\packages";
WebClient cln = new WebClient();
foreach (DataServicePackage elem in query)
{
string dir = path + "\\" + elem.Id;
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
cln.DownloadFile(elem.DownloadUrl.AbsoluteUri, (path + "\\" + elem.Id + "\\" + elem.Id + "." + elem.Version + ".nupkg"));
}
donderdag 1 november 2018
CSS3: box-sizing
Stel je hebt een element die height: 100% heeft. Dan krijg je een scrollbar op het moment dat je een margin of padding op het element zet.
Je kunt het probleem oplossen door de CSS3 attribuut box-sizing: border-box; te gebruiken op het element. De grootte van het element wordt dan berekend inclusief margin en padding.
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
Je kunt het probleem oplossen door de CSS3 attribuut box-sizing: border-box; te gebruiken op het element. De grootte van het element wordt dan berekend inclusief margin en padding.
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
donderdag 25 oktober 2018
donderdag 27 september 2018
Mongodb: rename database
In Robo 3T de database aanklikken en rechter muisknop en OpenShell selecteren.
Vervolgens invoeren:
db.copyDatabase("old_db_name","new_db_name")
use old_db_name
db.dropDatabase()
Vervolgens invoeren:
db.copyDatabase("old_db_name","new_db_name")
use old_db_name
db.dropDatabase()
woensdag 26 september 2018
Ontlast GUI-thread met async/await
Als je een winforms applicatie meer "responsive" wil maken, dan moet je de GUI-thread niet meer blokkeren.
Een eenvoudig manier om dat te doen is een method die veel tijd opsoepeert async te maken.
Je hebt bijvoorbeeld de volgende code:
using (var repo = new Repository(gitDir))
{ ...
Dit verander je in:
private Task<Repository> GetRepositoryAsync(string gitDir)
{
var task = Task<Repository>.Factory.StartNew(() => { return new Repository(gitDir); });
return task;
}
De method waarin je deze nieuwe function aanroept moet voorzien zijn van het async keyword. De aanroep van de function is als volgt:
using (var repo = await GetRepositoryAsync(gitDir))
{ ...
Een eenvoudig manier om dat te doen is een method die veel tijd opsoepeert async te maken.
Je hebt bijvoorbeeld de volgende code:
using (var repo = new Repository(gitDir))
{ ...
Dit verander je in:
private Task<Repository> GetRepositoryAsync(string gitDir)
{
var task = Task<Repository>.Factory.StartNew(() => { return new Repository(gitDir); });
return task;
}
De method waarin je deze nieuwe function aanroept moet voorzien zijn van het async keyword. De aanroep van de function is als volgt:
using (var repo = await GetRepositoryAsync(gitDir))
{ ...
zondag 23 september 2018
Low latency modes .net452
Je kunt ervoor zorgen dat er geen full garbage collect gebeurt tijdens tijdkritische zaken in .NET:
https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/latency
https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/latency
zondag 16 september 2018
Een ORM kan tegen je gaan werken...
Een Object Relational Mapper is ontzettend handig als je CRUD operations wil uitvoeren op tabellen. Maar ALLES proberen op te lossen met je ORM is verkeerd. Lees in deze post de ellende van iemand die dat probeert. Hij wil de volgende query door LLBLGen laten genereren:
SELECT
COUNT(DISTINCT(PstFileEntry.OwnerEntryIdOverride)) as [UserCount],
SUM(Size)/1024/1024 as FileSizeInMB
FROM PstFileUploadProgress a
INNER JOIN PstFileEntry ON a.PstFileEntryId = PstFileEntry.PstFileEntryId,
(SELECT PstFileUploadProgress.PstFileEntryId, max(PstFileUploadProgressDateTime) as max_date
FROM PstFileUploadProgress
GROUP BY PstFileUploadProgress.PstFileEntryId) b
WHERE a.PstFileEntryId = b.PstFileEntryId
AND a.PstFileUploadProgressDateTime = b.max_date
AND a.PstFileUploadProgressStatus = 1
Kansloze actie!
Dit zijn duidelijk handmatige queries. Voer deze query gewoon uit met ADO.NET.
ORM's zijn niet de oplossing voor alle SQL problemen!
SELECT
COUNT(DISTINCT(PstFileEntry.OwnerEntryIdOverride)) as [UserCount],
SUM(Size)/1024/1024 as FileSizeInMB
FROM PstFileUploadProgress a
INNER JOIN PstFileEntry ON a.PstFileEntryId = PstFileEntry.PstFileEntryId,
(SELECT PstFileUploadProgress.PstFileEntryId, max(PstFileUploadProgressDateTime) as max_date
FROM PstFileUploadProgress
GROUP BY PstFileUploadProgress.PstFileEntryId) b
WHERE a.PstFileEntryId = b.PstFileEntryId
AND a.PstFileUploadProgressDateTime = b.max_date
AND a.PstFileUploadProgressStatus = 1
Kansloze actie!
Dit zijn duidelijk handmatige queries. Voer deze query gewoon uit met ADO.NET.
ORM's zijn niet de oplossing voor alle SQL problemen!
zaterdag 15 september 2018
Gratis Thread/Tasks cursus op linkedin. Zou linkedin soms overgenomen zijn door Microsoft?
vrijdag 14 september 2018
bat file loop convert h265 to h264
for %%F in (*.mkv) do (
ffmpeg -i "%%~dpnxF" -c:v libx264 "h264-%%F"
)
ffmpeg -i "%%~dpnxF" -c:v libx264 "h264-%%F"
)
donderdag 13 september 2018
RTSP, RTP, SDP, RTP Payload for H264, H264
rtsp: https://tools.ietf.org/html/rfc7826
rtp: https://tools.ietf.org/html/rfc3550
sdp: https://tools.ietf.org/html/rfc4566
h264: https://www.google.nl/search?q=The_H.264_advanced_video_compression_standard
RTP Payload Format for H.264 Video: https://tools.ietf.org/html/rfc6184
rtp: https://tools.ietf.org/html/rfc3550
sdp: https://tools.ietf.org/html/rfc4566
h264: https://www.google.nl/search?q=The_H.264_advanced_video_compression_standard
RTP Payload Format for H.264 Video: https://tools.ietf.org/html/rfc6184
woensdag 29 augustus 2018
"Which" in powershell
Welke Java gebruik je in powershell?
Get-Command java
Get-Command java
donderdag 23 augustus 2018
Visual Studio 2017 nieuwe projectstructuur
Visual Studio 2017 ondersteunt een nieuwe csproj structuur die veel compacter en netter is.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452</TargetFrameworks>
<Version>1.0.0</Version>
<Authors>Auteur</Authors>
<Company>Bedrijf</Company>
<Description>Commentaar</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.0.2" />
</ItemGroup>
</Project>
Het voordeel van de nieuwe structuur is dat er automatisch een nuget package wordt aangemaakt, die je kunt uploaden naar je asset repository (wellicht nexus):
nuget push -src http://nexus.place.local/repository/bla-publish/ ThePackage.1.1.3.nupkg
deleten met:
nuget delete ThePackage 1.1.3 -src http://nexus.place.local/repository/bla-publish/
Vergeet niet dat de packages gecached worden. Die cache kun je ook weet legen:
nuget locals all -list
nuget locals all -clear
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452</TargetFrameworks>
<Version>1.0.0</Version>
<Authors>Auteur</Authors>
<Company>Bedrijf</Company>
<Description>Commentaar</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.0.2" />
</ItemGroup>
</Project>
Het voordeel van de nieuwe structuur is dat er automatisch een nuget package wordt aangemaakt, die je kunt uploaden naar je asset repository (wellicht nexus):
nuget push -src http://nexus.place.local/repository/bla-publish/ ThePackage.1.1.3.nupkg
deleten met:
nuget delete ThePackage 1.1.3 -src http://nexus.place.local/repository/bla-publish/
Vergeet niet dat de packages gecached worden. Die cache kun je ook weet legen:
nuget locals all -list
nuget locals all -clear
dinsdag 7 augustus 2018
ffmpeg compile x64 visual studio 2017
I managed to compile ffmpeg 64-bit using visual studio 2017:
This page helps, but some info is not copy/pasted correctly. Here is my corrected version:
* Download "MSYS2 x86_64" from "http://msys2.github.io" and install into "C:\workspace\windows\msys64"
* Open the "x64 Native Tools prompt" from the Visual Studio 2017 folder.
* C:\workspace\windows\msys64\msys2_shell.cmd -mingw64 -use-full-path
(this will open a new window)
(inside the MSYS2 shell install the following packages)
* pacman -S make gcc diffutils mingw-w64-{i686,x86_64}-pkg-config mingw-w64-x86_64-nasm mingw-w64-x86_64-yasm
* Rename C:\workspace\windows\msys64\usr\bin\link.exe to C:\workspace\windows\msys64\usr\bin\link_orig.exe, in order to use MSVC link.exe
(or use mv /usr/bin/link.exe /usr/bin/link_old.exe in the shell)
### optionally install and compile x264
* git clone http://git.videolan.org/git/x264.git
* cd x264
* CC=cl ./configure --enable-static --prefix=/usr/local --disable-cli
* make
* make install
### ffmpeg
### Download sources from "http://www.ffmpeg.org/download.html"
# cd ffmpeg
* export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
(the next step can take quiet a while. Please wait)
* ./configure --toolchain=msvc --arch=x86_64 --enable-yasm --enable-asm --enable-shared --disable-static --disable-programs --enable-avresample --enable-libx264 --enable-gpl --prefix=./install
* make
* make install
This page helps, but some info is not copy/pasted correctly. Here is my corrected version:
* Download "MSYS2 x86_64" from "http://msys2.github.io" and install into "C:\workspace\windows\msys64"
* Open the "x64 Native Tools prompt" from the Visual Studio 2017 folder.
* C:\workspace\windows\msys64\msys2_shell.cmd -mingw64 -use-full-path
(this will open a new window)
(inside the MSYS2 shell install the following packages)
* pacman -S make gcc diffutils mingw-w64-{i686,x86_64}-pkg-config mingw-w64-x86_64-nasm mingw-w64-x86_64-yasm
* Rename C:\workspace\windows\msys64\usr\bin\link.exe to C:\workspace\windows\msys64\usr\bin\link_orig.exe, in order to use MSVC link.exe
(or use mv /usr/bin/link.exe /usr/bin/link_old.exe in the shell)
### optionally install and compile x264
* git clone http://git.videolan.org/git/x264.git
* cd x264
* CC=cl ./configure --enable-static --prefix=/usr/local --disable-cli
* make
* make install
### ffmpeg
### Download sources from "http://www.ffmpeg.org/download.html"
# cd ffmpeg
* export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
(the next step can take quiet a while. Please wait)
* ./configure --toolchain=msvc --arch=x86_64 --enable-yasm --enable-asm --enable-shared --disable-static --disable-programs --enable-avresample --enable-libx264 --enable-gpl --prefix=./install
* make
* make install
donderdag 2 augustus 2018
Lua: predictable Garbage Collection
http://kalogirou.net/2011/07/23/predictable-garbage-collection-with-lua/#disqus_thread
Update 22-12-2018: Je kan beter http://www.squirrel-lang.org/ gebruiken i.p.v. lua. Squirrel heeft reference counting als geheugenbeheer. Veel beter voor realtime toepassingen.
Update 22-12-2018: Je kan beter http://www.squirrel-lang.org/ gebruiken i.p.v. lua. Squirrel heeft reference counting als geheugenbeheer. Veel beter voor realtime toepassingen.
vrijdag 20 juli 2018
WebRTC: realtime video in the webbrowser
https://webrtc.org/
http://webrtc.live555.com/
MSE (Media Source Extensions) heeft een latency: https://www.linkingvision.com/rtsp_in_html5_with_low_latency
http://webrtc.live555.com/
MSE (Media Source Extensions) heeft een latency: https://www.linkingvision.com/rtsp_in_html5_with_low_latency
zaterdag 14 juli 2018
Avalon Edit
http://avalonedit.net/
http://danielgrunwald.de/coding/AvalonEdit/rendering.php
https://www.codeproject.com/Articles/42490/Using-AvalonEdit-WPF-Text-Editor
AvalonEdit is niet zozeer geschikt als rich teksteditor, want je kunt niet zomaar een woord een andere kleur geven. Dan worden alle woorden die gelijk zijn ook die kleur. Het is dus echt bedoeld als codeeditor.
http://danielgrunwald.de/coding/AvalonEdit/rendering.php
https://www.codeproject.com/Articles/42490/Using-AvalonEdit-WPF-Text-Editor
AvalonEdit is niet zozeer geschikt als rich teksteditor, want je kunt niet zomaar een woord een andere kleur geven. Dan worden alle woorden die gelijk zijn ook die kleur. Het is dus echt bedoeld als codeeditor.
Kleinste H.264 encoder
https://cardinalpeak.com/blog/worlds-smallest-h-264-encoder/
RSTP:
https://archive.codeplex.com/?p=net7mma
https://www.codeproject.com/Articles/507218/Managed-Media-Aggregation-using-Rtsp-and-Rtp
https://en.wikipedia.org/wiki/Session_Description_Protocol
https://www.ietf.org/rfc/rfc1889.txt (RTP)
https://www.ietf.org/rfc/rfc2326.txt (RTSP)
https://github.com/ngraziano/SharpRTSP
H264: https://sidbala.com/h-264-is-magic/
zondag 17 juni 2018
RabbitMQ installeren
Eerst otp_win64_20.1.exe installeren.
Daarna rabbitmq-server-3.7.5.exe
rabbitmq-plugins enable rabbitmq_management
http://localhost:15672/ guest guest
rabbitmqctl status
rabbitmqctl add_user reneo <password>
rabbitmqctl set_user_tags reneo administrator
rabbitmqctl set_permissions -p / reneo ".*" ".*" ".*"
Daarna rabbitmq-server-3.7.5.exe
rabbitmq-plugins enable rabbitmq_management
http://localhost:15672/ guest guest
rabbitmqctl status
rabbitmqctl add_user reneo <password>
rabbitmqctl set_user_tags reneo administrator
rabbitmqctl set_permissions -p / reneo ".*" ".*" ".*"
donderdag 31 mei 2018
WPF
Using Commands:
http://www.wpf-tutorial.com/commands/using-commands/
Markup Extensions:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/markup-extensions-and-wpf-xaml
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/binding-markup-extension
Avalon Edit:
http://danielgrunwald.de/coding/AvalonEdit/rendering.php
https://www.codeproject.com/Articles/42490/Using-AvalonEdit-WPF-Text-Editor
http://avalonedit.net/
http://www.wpf-tutorial.com/commands/using-commands/
Markup Extensions:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/markup-extensions-and-wpf-xaml
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/binding-markup-extension
Avalon Edit:
http://danielgrunwald.de/coding/AvalonEdit/rendering.php
https://www.codeproject.com/Articles/42490/Using-AvalonEdit-WPF-Text-Editor
http://avalonedit.net/
woensdag 25 april 2018
Inspect return value in Visual Studio
You can add a watch for expression $ReturnValue and that will contain the return value.
zondag 15 april 2018
vrijdag 6 april 2018
Visual Studio ideaal voor C++ / x64 assembler programming
Visual Studio is echt ideaal voor debugging C++ / x64 assembler code.
Tijdens het debuggen kun je ctrl-alt-d drukken om assembly code van de C++ code te zien.
Ook kun je de inhoud van de registers zien. Tevens van de stack, met Debug/Windows/Memory/Memory1.
In je header file van je C++ class definieer je een extern naar een assembler file als volgt:
extern "C" void RotateScreenPart(BYTE* screenSource, BYTE* screenDestination, Sint64 startY, Sint64 endY, Sint64 cosinusAngle, Sint64 sinusAngle, Sint64 centerPointX, Sint64 centerPointY, Sint64 screenWidth, Sint64 screenHeight);
Tijdens het debuggen kun je ctrl-alt-d drukken om assembly code van de C++ code te zien.
Ook kun je de inhoud van de registers zien. Tevens van de stack, met Debug/Windows/Memory/Memory1.
In je header file van je C++ class definieer je een extern naar een assembler file als volgt:
extern "C" void RotateScreenPart(BYTE* screenSource, BYTE* screenDestination, Sint64 startY, Sint64 endY, Sint64 cosinusAngle, Sint64 sinusAngle, Sint64 centerPointX, Sint64 centerPointY, Sint64 screenWidth, Sint64 screenHeight);
Vergeet niet deze typedef's op te nemen:
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef uint8_t BYTE;
typedef uint16_t Uint16;
typedef int16_t Sint16;
typedef uint32_t Uint32;
typedef int32_t Sint32;
typedef uint64_t Uint64;
typedef int64_t Sint64;
In je assembler file doe je:
RotateScreenPart proc
push rbp
mov rbp, rsp
sub rsp, 30h ; 6 qwords space.
mov [rbp-8h], r8
mov [rbp-10h], r9
mov [rbp-18h], rcx
mov [rbp-20h], rdx
push rax
mov rax, 1566 - 100
mov [rbp-28h], rax
mov rax, 1566 - 200
mov [rbp-30h], rax
push rbx
; cosinusAngle = [rbp+30h]
; sinusAngle = [rbp+38h]
; centerPointX = [rbp+40h]
; centerPointY = [rbp+48h]
; screenWidth = [rbp+50h]
pop rbx
pop rax
mov rsp, rbp
pop rbp
ret
RotateScreenPart endp
Aan de bovenstaande code zie je dat de
parameter1 = rcx
parameter2 = rdx
parameter3 = r8
parameter4 = r9
mov rax, [rbp+30h] ; parameter 5
mov rax, [rbp+38h] ; parameter 6
Je kunt ook nog lokale space aanmaken. Zie RotateScreenPart.
Visual Studio C++ resource toevoegen
Je kunt in Visual Studio C++ makkelijk een resource toevoegen, zodat je bijvoorbeeld een plaatje niet van disk hoeft te laden.
Je doet rechter muisknop -> Add.. -> Resource... -> Custom... -> RCDATA (invullen in textbox).
Vervolgens moet je bytes invullen. Je tikt wat in.
Vervolgens kijk je hoe het nieuwe bestand op schijf heet, en overschijft 'm met jouw juiste bestand.
Vervolgens kun je in C++ op de volgende manier je resource inladen:
HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA2), RT_RCDATA);
unsigned int myResourceSize = ::SizeofResource(NULL, myResource);
HGLOBAL myResourceData = ::LoadResource(NULL, myResource);
void* pMyBinaryData = ::LockResource(myResourceData);
unsigned char* buffer = (unsigned char*)pMyBinaryData;
Je doet een LockResource en dan verwacht je dat je weer iets moet vrijgeven. Dat hoeft echter niet volgens bronnen op Internet.
Je doet rechter muisknop -> Add.. -> Resource... -> Custom... -> RCDATA (invullen in textbox).
Vervolgens moet je bytes invullen. Je tikt wat in.
Vervolgens kijk je hoe het nieuwe bestand op schijf heet, en overschijft 'm met jouw juiste bestand.
Vervolgens kun je in C++ op de volgende manier je resource inladen:
HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA2), RT_RCDATA);
unsigned int myResourceSize = ::SizeofResource(NULL, myResource);
HGLOBAL myResourceData = ::LoadResource(NULL, myResource);
void* pMyBinaryData = ::LockResource(myResourceData);
unsigned char* buffer = (unsigned char*)pMyBinaryData;
Je doet een LockResource en dan verwacht je dat je weer iets moet vrijgeven. Dat hoeft echter niet volgens bronnen op Internet.
dinsdag 3 april 2018
Volatile C++ variables
// at the module level or somewhere else global to the function
int n;
while (n > 0) { count++; }
will be readily transformed by an optimizing compiler as
if(n > 0)
for(;;)
count++;
and this is a perfectly valid translation. Because there is nothing in the loop that can change the value of n, there is no reason to ever test it again! This optimization is an example of a loop invariant computation, and an optimizing compiler will "pull this out" of the loop.
But what if the rest of the program looked like this:
registerMyThreadFlag(&n);
while(n > 0)
{
count++;
}
and the thread used the variable registered by the registerMyThreadFlag call to set the value of the variable whose address was passed in? It would fail utterly; the loop would never exit!
Thus, the way this would have to be declared is by adding the volatile attribute to the declaration of n:
volatile int n;
This informs the compiler that it does not have the freedom to make the assumption about constancy of the value. The compiler will generate code to test the value n on every iteration through the loop, because you've explicitly told it that it is not safe to assume the value n is loop-invariant.
int n;
while (n > 0) { count++; }
will be readily transformed by an optimizing compiler as
if(n > 0)
for(;;)
count++;
and this is a perfectly valid translation. Because there is nothing in the loop that can change the value of n, there is no reason to ever test it again! This optimization is an example of a loop invariant computation, and an optimizing compiler will "pull this out" of the loop.
But what if the rest of the program looked like this:
registerMyThreadFlag(&n);
while(n > 0)
{
count++;
}
and the thread used the variable registered by the registerMyThreadFlag call to set the value of the variable whose address was passed in? It would fail utterly; the loop would never exit!
Thus, the way this would have to be declared is by adding the volatile attribute to the declaration of n:
volatile int n;
This informs the compiler that it does not have the freedom to make the assumption about constancy of the value. The compiler will generate code to test the value n on every iteration through the loop, because you've explicitly told it that it is not safe to assume the value n is loop-invariant.
zaterdag 31 maart 2018
SDL2 Play MP3 or XM
Mix_Music *music = NULL;
For MP3:
Mix_Init(MIX_INIT_MP3);
Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
Mix_Music *music = Mix_LoadMUS("c:\\assembly\\Tennisballen\\x64\\Debug\\test.mp3");
Mix_PlayMusic(music, 1);
or for XM:
Mix_Init(MIX_INIT_MOD);
Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
Mix_Music *music = Mix_LoadMUS("c:\\assembly\\Tennisballen\\x64\\Debug\\tip - kool.xm");
Mix_PlayMusic(music, 1);
To End the music:
Mix_FreeMusic(music);
For MP3:
Mix_Init(MIX_INIT_MP3);
Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
Mix_Music *music = Mix_LoadMUS("c:\\assembly\\Tennisballen\\x64\\Debug\\test.mp3");
Mix_PlayMusic(music, 1);
or for XM:
Mix_Init(MIX_INIT_MOD);
Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
Mix_Music *music = Mix_LoadMUS("c:\\assembly\\Tennisballen\\x64\\Debug\\tip - kool.xm");
Mix_PlayMusic(music, 1);
To End the music:
Mix_FreeMusic(music);
woensdag 28 maart 2018
SDL2 static link
- Download the SDL2 sources.
- Select release configuration.
- In the VisualC folder, open the visual studio solution.
- Change the type of project for SDL2 and SDL2main: General -> Configuration Type -> Static Library
- Configuration Properties -> C/C++ -> Code Generation -> Runtime Library : Multi-threaded (/MT)
- You should obtain: SDL2.lib and SDL2main.lib
Here is the list of dependencies to add in the Linker -> Input of the project you want to compile:
winmm.lib
imm32.lib
version.lib
These libraries are already included in visual studio so it should not be necessary to include them with other lib files.
vrijdag 23 maart 2018
Hoe sinus functie te implementeren
Dit is een interessant antwoord op stackoverflow over hoe je een sinus functie kunt implementeren.
maandag 19 maart 2018
SDL2 fastest way to draw pixels
When your monitor sync is 60 herz, you've got 16 ms to do your pixel update.
I managed to clear a 1366 by 768 pixelbuffer and upload it to the graphicscard in 0.60ms. This leaves 15 ms to do pixel magic.
In SDL 2, I do the following:
#define DIMx 1366
#define DIMy 768
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,DIMx, DIMy,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN */);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED /*| SDL_RENDERER_PRESENTVSYNC */);
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, DIMx, DIMy);
SDL_Surface* surface = SDL_CreateRGBSurface(0, DIMx, DIMy, 32, 0, 0, 0, 0);
BYTE* pixels = (BYTE *)surface->pixels;
SDL_Event event;
bool running = true;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
while (running)
{
int pitch = DIMx * 4;
SDL_LockTexture(texture, NULL, (void **)&pixels, &pitch);
ClearArray(pixels, (DIMx*DIMy/2) ); //0.15 ms (asm: rep stosq)
pixels[0] = 255; //set just one pixel, for example
pixels[1] = 255;
pixels[2] = 255;
pixels[3] = 255;
SDL_UnlockTexture(texture);
SDL_RenderCopyEx(renderer, texture, NULL, NULL, 0.0f, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
}
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
I hope you can use this code. Activate the SDL_RENDERER_PRESENTVSYNC to have a smooth 60 herz.
I managed to clear a 1366 by 768 pixelbuffer and upload it to the graphicscard in 0.60ms. This leaves 15 ms to do pixel magic.
In SDL 2, I do the following:
#define DIMx 1366
#define DIMy 768
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,DIMx, DIMy,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN */);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED /*| SDL_RENDERER_PRESENTVSYNC */);
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, DIMx, DIMy);
SDL_Surface* surface = SDL_CreateRGBSurface(0, DIMx, DIMy, 32, 0, 0, 0, 0);
BYTE* pixels = (BYTE *)surface->pixels;
SDL_Event event;
bool running = true;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
while (running)
{
int pitch = DIMx * 4;
SDL_LockTexture(texture, NULL, (void **)&pixels, &pitch);
ClearArray(pixels, (DIMx*DIMy/2) ); //0.15 ms (asm: rep stosq)
pixels[0] = 255; //set just one pixel, for example
pixels[1] = 255;
pixels[2] = 255;
pixels[3] = 255;
SDL_UnlockTexture(texture);
SDL_RenderCopyEx(renderer, texture, NULL, NULL, 0.0f, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
}
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
Binair bestand downloaden vanuit Javascript
In een eerdere blog heb ik al eens geschreven over createObjectURL, namelijk bij het direct printen vanuit Chrome.
Ook voor het laten downloaden van binaire bestanden is de functie window.URL.createObjectURL handig.
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
var saveByteArray = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var sampleBytes = base64ToArrayBuffer('R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs');
saveByteArray([sampleBytes], 'black1x1.bin');
Voer deze javascript uit en Chrome download meteen een file genaamd black1x1.bin. Lijkt me zelfs een beetje onwenselijk dat een website zomaar een bestand kan laten downloaden zonder dat je ergens op klikt...
Ook voor het laten downloaden van binaire bestanden is de functie window.URL.createObjectURL handig.
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
var saveByteArray = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var sampleBytes = base64ToArrayBuffer('R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs');
saveByteArray([sampleBytes], 'black1x1.bin');
Voer deze javascript uit en Chrome download meteen een file genaamd black1x1.bin. Lijkt me zelfs een beetje onwenselijk dat een website zomaar een bestand kan laten downloaden zonder dat je ergens op klikt...
zondag 18 maart 2018
Assembler is sneller dan C++
Gisteren een video gezien van een Assembler expert die uitdrukkelijk beweert dat het een leugen is dat C++ tegenwoordig sneller is dan Assembler.
Laten we een test doen. Bijvoorbeeld een array vullen met 0.
Om maximaal nut te hebben van de 64bits architectuur doe ik het volgende in C++:
Uint64* pixels64bit = (Uint64 *)pixels;
for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
Bovenstaande loop duurt 1.05ms.
Nu in Assembler:
ClearArray proc
push rdi
xchg rcx, rdx
mov rdi, rdx
xor rax, rax
rep stosq
pop rdi
ret
ClearArray endp
En dat duurt 0.15ms.
Hoe komt het dat de Assembler versie 8 keer sneller is? Als we naar de gegenereerde code van C++ kijken, dan zien we het:
CPP: Uint64* pixels64bit = (Uint64 *)pixels;
00007FF7F1CE1A9A mov rax,qword ptr [pixels]
00007FF7F1CE1AA1 mov qword ptr [rbp+218h],rax
CPP: for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
00007FF7F1CE1AA8 mov dword ptr [rbp+234h],0
00007FF7F1CE1AB2 jmp wWinMain+1E2h (07FF7F1CE1AC2h)
00007FF7F1CE1AB4 mov eax,dword ptr [rbp+234h]
00007FF7F1CE1ABA inc eax
00007FF7F1CE1ABC mov dword ptr [rbp+234h],eax
00007FF7F1CE1AC2 cmp dword ptr [rbp+234h],80100h
00007FF7F1CE1ACC jge wWinMain+206h (07FF7F1CE1AE6h)
00007FF7F1CE1ACE movsxd rax,dword ptr [rbp+234h]
00007FF7F1CE1AD5 mov rcx,qword ptr [rbp+218h]
00007FF7F1CE1ADC mov qword ptr [rcx+rax*8],0
00007FF7F1CE1AE4 jmp wWinMain+1D4h (07FF7F1CE1AB4h)
Dit kan dus nooit sneller zijn, dan de rep stosq.
Trouwens, een C++ functie zoals:
std::fill(pixels64bit, pixels64bit + (DIMx*DIMy/2), 0);
duurt ook ruim 1.00ms.
Laten we een test doen. Bijvoorbeeld een array vullen met 0.
Om maximaal nut te hebben van de 64bits architectuur doe ik het volgende in C++:
Uint64* pixels64bit = (Uint64 *)pixels;
for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
Bovenstaande loop duurt 1.05ms.
Nu in Assembler:
ClearArray proc
push rdi
xchg rcx, rdx
mov rdi, rdx
xor rax, rax
rep stosq
pop rdi
ret
ClearArray endp
En dat duurt 0.15ms.
Hoe komt het dat de Assembler versie 8 keer sneller is? Als we naar de gegenereerde code van C++ kijken, dan zien we het:
CPP: Uint64* pixels64bit = (Uint64 *)pixels;
00007FF7F1CE1A9A mov rax,qword ptr [pixels]
00007FF7F1CE1AA1 mov qword ptr [rbp+218h],rax
CPP: for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
00007FF7F1CE1AA8 mov dword ptr [rbp+234h],0
00007FF7F1CE1AB2 jmp wWinMain+1E2h (07FF7F1CE1AC2h)
00007FF7F1CE1AB4 mov eax,dword ptr [rbp+234h]
00007FF7F1CE1ABA inc eax
00007FF7F1CE1ABC mov dword ptr [rbp+234h],eax
00007FF7F1CE1AC2 cmp dword ptr [rbp+234h],80100h
00007FF7F1CE1ACC jge wWinMain+206h (07FF7F1CE1AE6h)
00007FF7F1CE1ACE movsxd rax,dword ptr [rbp+234h]
00007FF7F1CE1AD5 mov rcx,qword ptr [rbp+218h]
00007FF7F1CE1ADC mov qword ptr [rcx+rax*8],0
00007FF7F1CE1AE4 jmp wWinMain+1D4h (07FF7F1CE1AB4h)
Dit kan dus nooit sneller zijn, dan de rep stosq.
Trouwens, een C++ functie zoals:
std::fill(pixels64bit, pixels64bit + (DIMx*DIMy/2), 0);
duurt ook ruim 1.00ms.
zondag 4 maart 2018
fading text
When there is a lot of text to be read, you can fade it to white and give a option to read the rest of the text. This is how it is done in css. You put a gradient absolute positioned block over it.
https://jsfiddle.net/pz1nsrLw/14/
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
</div>
height: 100px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
#fading:after {
content:'';
width:100%;
height:5rem;
position:absolute;
left:0;
bottom:0;
background-color: black;
background:linear-gradient(rgba(255,255,255,0), #fff);
}
https://jsfiddle.net/pz1nsrLw/14/
html
<div id="fading">Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
</div>
css
#fading {height: 100px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
#fading:after {
content:'';
width:100%;
height:5rem;
position:absolute;
left:0;
bottom:0;
background-color: black;
background:linear-gradient(rgba(255,255,255,0), #fff);
}
vrijdag 2 maart 2018
Welke events zijn er met jquery gekoppeld aan een object?
Op de volgende manier kun je kijken welke events jquery gekoppeld heeft op het object window:
$._data( $(window)[0], "events" )
$._data( $(window)[0], "events" )
maandag 26 februari 2018
Stacktrace.js
Generate, parse, and enhance JavaScript stack traces in all web browsers.
Stacktrace.js
Stacktrace.js
vrijdag 23 februari 2018
Toevoegen van DOM nodes bemerken via animationstart
Er is nog een andere manier om het toevoegen van nodes in javascript te bemerken. Via animationstart!
Het is ongelovelijk, maar het werkt. De app sentinel maakt er gebruik van.
Het is ongelovelijk, maar het werkt. De app sentinel maakt er gebruik van.
woensdag 21 februari 2018
Veranderingen in de DOM bemerken via javascript
Stel je wilt het verwijderen van een element genaamd spaForm bemerken via javascript. Je kunt dan MutationObserver gebruiken.
function spaFormRemovalCallback( callback) {
var spaFormNotifier = new MutationObserver(function(e) {
var j = 0;
for (j = 0; j < e.length; j++) {
var removedNodes = e[j].removedNodes;
if (removedNodes.length > 0) {
var i = 0;
for (i = 0; i < removedNodes.length; i++) {
if ((node.id === "spaForm") && (node.nodeName === "FORM")) {
callback();
} }
}
}
});
var spaFormNode = $("#spaForm");
if (spaFormNode.length > 0 && spaFormNode.parent().length > 0) {
spaFormNotifier. observe(spaFormNode.parent( )[0], { childList: true });
}
}
vrijdag 9 februari 2018
Toolbar to the left on equal level
See: https://jsfiddle.net/kjtmq0us/3/
html
<div class="sideBarEqual">Side info!</div>
<div class="baseNode">
<div class="toolbar">Toolbar</div>
<div class="theContent">
very much content...
</div>
</div>
css
body {
margin: 0;
padding: 0;
height: 100vh;
background-color: yellow;
overflow: hidden;
display: flex;
flex-direction: row;
}
.baseNode {
flex: 1 1 auto;
}
.toolbar {
background-color: red;
height: 40px;
}
.theContent {
background-color: blue;
height: calc(100vh - 40px);
overflow: auto;
}
.sideBarEqual {
flex: 0 0 120px;
background-color: purple;
color: yellow;
}
.sideBarOverlay {
position: fixed;
left: 0px;
top: 0px;
width: 120px;
height: 100vh;
background-color: purple;
opacity: 1.0;
color: yellow;
}
html
<div class="sideBarEqual">Side info!</div>
<div class="baseNode">
<div class="toolbar">Toolbar</div>
<div class="theContent">
very much content...
</div>
</div>
css
body {
margin: 0;
padding: 0;
height: 100vh;
background-color: yellow;
overflow: hidden;
display: flex;
flex-direction: row;
}
.baseNode {
flex: 1 1 auto;
}
.toolbar {
background-color: red;
height: 40px;
}
.theContent {
background-color: blue;
height: calc(100vh - 40px);
overflow: auto;
}
.sideBarEqual {
flex: 0 0 120px;
background-color: purple;
color: yellow;
}
.sideBarOverlay {
position: fixed;
left: 0px;
top: 0px;
width: 120px;
height: 100vh;
background-color: purple;
opacity: 1.0;
color: yellow;
}
div height rest of page
See: https://jsfiddle.net/kjtmq0us/2/
Suppose, we have a toolbar, and want to fill the remaining of the height of the page. You can do it as follows:
body {
margin: 0;
padding: 0;
height: 100%;
background-color: yellow;
overflow: hidden;
}
.toolbar {
background-color: red;
height: 40px;
}
.theContent {
background-color: blue;
height: calc(100vh - 40px);
overflow: auto;
}
html:
<div class="baseFlex">
<div class="toolbar">Toolbar</div>
<div class="theContent">
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
1234234 5345645 6756781 234234 5345656 76787896 1234234 534564 567657812 3412344321
</div>
</div>
css:
body {
margin: 0;
padding: 0;
height: 100%;
background-color: yellow;
overflow: hidden;
}
.baseFlex {
display: flex;
flex-direction: column;
height: 100%;
overflow: auto;
}
.toolbar {
background-color: red;
flex-grow: 0;
flex-shrink: 0;
flex-basis: 40px;
}
.theContent {
background-color: blue;
flex-grow: 1;
flex-shrink: 1;
flex-basis: calc(100vh - 40px);
overflow: auto;
}
Abonneren op:
Posts (Atom)