したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | メール | |

管理人の独り言(プログラミング関連)

1みみず★:2008/08/10(日) 23:28:15
あまりにもプログラミングの内容が増えすぎた。
よって隔離スレの中を更に隔離。

2403774さん:2010/07/20(火) 15:08:22
早くOllyDbgがWin64の実行ファイルもデバッグできるようになればいいんだ!

2404774さん:2010/07/20(火) 15:47:03
C++0xが出たら、一体関数宣言はどうすればいいだろうか。
俺は
auto FuncName() -> void;
と書くべきだと思う。
そういえば、
[]FuncName()->void;と書く案はどうなったのだ?

2405774さん:2010/07/20(火) 16:35:08
問:以下のソースを全く同じ動作をするコードを書け。(定数時間)
-----
auto CTest1::TestFunction(unsigned int a, unsigned int b)->unsigned int{
unsigned int ret = 0;
for(unsigned int i = a; i <= b; ++i){
ret += i;
}
return ret;
}
-----
俺には書けなかった・・・
TestFunction(0xfffffffe, 0xfffffffe);
TestFunction(n, 0xffffffff);
あたりを再現できるかが肝心だな。
多分無理だと思うのだが。

2406774さん:2010/07/20(火) 16:35:46
>>2405
についてはunsigned intは32bitsで。

2407774さん:2010/07/20(火) 16:37:13
こんなことやってて、virtualな関数とそうでない関数の呼び出し速度の違いを計るのを忘れていた。

2408774さん:2010/07/20(火) 16:52:38
-m32とか付けるだけで32bitでコンパイルできる。

2409774さん:2010/07/20(火) 17:16:43
もはや最適化で何をやっているのかが分からない。
-----

CPU Disasm
Address Hex dump Command Comments
004019C1 |. /EB 04 JMP SHORT 004019C7
004019C3 |> |660F6FC5 /MOVDQA XMM0,XMM5
004019C7 |> \660F6FD0 |MOVDQA XMM2,XMM0
004019CB |. 660FFED3 |PADDD XMM2,XMM3
004019CF |. 660F6FF8 |MOVDQA XMM7,XMM0
004019D3 |. 660F6FF2 |MOVDQA XMM6,XMM2
004019D7 |. 660F72D6 01 |PSRLD XMM6,1
004019DC |. 660F73DF 04 |PSRLDQ XMM7,4
004019E1 |. 660F6FE6 |MOVDQA XMM4,XMM6
004019E5 |. 660F73DE 04 |PSRLDQ XMM6,4
004019EA |. 660FF4E0 |PMULUDQ XMM4,XMM0
004019EE |. 660F6F2D 8030 |MOVDQA XMM5,DQWORD PTR DS:[473080]
004019F6 |. 660FF4F7 |PMULUDQ XMM6,XMM7
004019FA |. 660FFEE8 |PADDD XMM5,XMM0
004019FE |. 660F72D0 01 |PSRLD XMM0,1
00401A03 |. 660F6FCA |MOVDQA XMM1,XMM2
00401A07 |. 660F70F6 08 |PSHUFD XMM6,XMM6,08
00401A0C |. 660F70E4 08 |PSHUFD XMM4,XMM4,08
00401A11 |. 660F62E6 |PUNPCKLDQ XMM4,XMM6
00401A15 |. 660F6FF0 |MOVDQA XMM6,XMM0
00401A19 |. 660F73D8 04 |PSRLDQ XMM0,4
00401A1E |. 660FF4F2 |PMULUDQ XMM6,XMM2
00401A22 |. 660FDBCB |PAND XMM1,XMM3
00401A26 |. 660F73DA 04 |PSRLDQ XMM2,4
00401A2B |. 660FF4D0 |PMULUDQ XMM2,XMM0
00401A2F |. 660F70C6 08 |PSHUFD XMM0,XMM6,08
00401A34 |. 660F70D2 08 |PSHUFD XMM2,XMM2,08
00401A39 |. 660F62C2 |PUNPCKLDQ XMM0,XMM2
00401A3D |. 660FEFD2 |PXOR XMM2,XMM2
00401A41 |. 660F76CA |PCMPEQD XMM1,XMM2
00401A45 |. 660FDBE1 |PAND XMM4,XMM1
00401A49 |. 660FDFC8 |PANDN XMM1,XMM0
00401A4D |. 660FEBCC |POR XMM1,XMM4
00401A51 |. 660F7F08 |MOVDQA DQWORD PTR DS:[EAX],XMM1
00401A55 |. 83C0 10 |ADD EAX,10
00401A58 |. 39D0 |CMP EAX,EDX
00401A5A |.^ 0F85 63FFFFFF \JNE 004019C3

2410774さん:2010/07/20(火) 17:18:39
>>2409
多分ベクトル化しているんだろう。

2411774さん:2010/07/20(火) 17:21:31
virtualと非virtualを測定しているが、100000回程度では差がない。

2412774さん:2010/07/20(火) 17:28:01
繰り返し回数を変えたら原因不明のバグに悩まされた。
と思ったら、ただ単にスタック上に変数を取り過ぎただけだった。

2413774さん:2010/07/20(火) 17:31:25
10000000回にしたら、最適化無しで10ms差が出た。
最適化すると25ms差が出たがこれはベクトル化のお陰だと思う。

2414774さん:2010/07/20(火) 17:33:53
更に十倍の繰り返し回数にしたら90強の差になった。(最適化なし)
最適化だと250ms強ぐらい。
妥当な結果過ぎてつまらん。

2415774さん:2010/07/20(火) 17:40:21
差を全部仮想関数呼出のコストだとすると、一回あたり、0.000001msぐらいのコスト。
しかし、実際はインライン化出来ない、繰り返しの時にベクトル化出来ない等様々な残念な点がある。
場合によっては倍かかる場合もあり得る。

2416774さん:2010/07/20(火) 17:40:32
#include <iostream>
#include <cstring>
#include <windows.h>

#define nullptr NULL

class ITest{
public:
virtual auto TestFunction(unsigned int a, unsigned int b)->unsigned int = 0;
};

class CTest1 : public ITest{
public:
virtual auto TestFunction(unsigned int a, unsigned int b)->unsigned int;
};
class CTest2 : public ITest{
public:
virtual auto TestFunction(unsigned int a, unsigned int b)->unsigned int;
};

auto CTest1::TestFunction(unsigned int a, unsigned int b)->unsigned int{
unsigned int ret = 0;
for(unsigned int i = a; i <= b; ++i){
ret += i;
}
return ret;
}

auto CTest2::TestFunction(unsigned int a, unsigned int b)->unsigned int{
if(a <= b){
//普通
unsigned int n = b - a + 1;
unsigned int s = a + b;
if(n & 1){
//項数が奇数
return (s >> 1) * n;
}else{
//項数が偶数
return (n >> 1) * s;
}
}else{
//まず来ない
return 0;
}
}

auto memcpy_ore(void *dust, const void *source, std::size_t size)->void{
char *p = static_cast<char*>(dust);
const char *q = static_cast<const char*>(source);
while(size--)*p++=*q++;
}

auto main(int argc, char **argv)->int{
const unsigned int count = 100000000u;

timeBeginPeriod(1);

CTest1 ct1;
CTest2 ct2;
ITest *it[] = {&ct1, &ct2};

static unsigned int rets[count];
/*
{
DWORD start = timeGetTime();
for(unsigned int i = 0u; i < count; ++i){
rets[i] = ct1.TestFunction(0, i);
}
DWORD end = timeGetTime();

std::cout << "start:" << start << ",end:" << end << "," << (end - start) << "ms" << std::endl;
}

if((DWORD)&rets <= 0xffff){
MessageBox((HWND)&rets, nullptr, nullptr, MB_OK);
}
*/
{
DWORD start = timeGetTime();
for(unsigned int i = 0u; i < count; ++i){
rets[i] = ct2.TestFunction(0, i);
}
DWORD end = timeGetTime();

std::cout << "start:" << start << ",end:" << end << "," << (end - start) << "ms" << std::endl;
}

if((DWORD)&rets <= 0xffff){
MessageBox((HWND)&rets, nullptr, nullptr, MB_OK);
}
/*
{
DWORD start = timeGetTime();
for(unsigned int i = 0u; i < count; ++i){
rets[i] = it[0]->TestFunction(0, i);
}
DWORD end = timeGetTime();

std::cout << "start:" << start << ",end:" << end << "," << (end - start) << "ms" << std::endl;
}

if((DWORD)&rets <= 0xffff){
MessageBox((HWND)&rets, nullptr, nullptr, MB_OK);
}
*/
{
DWORD start = timeGetTime();
for(unsigned int i = 0u; i < count; ++i){
rets[i] = it[1]->TestFunction(0, i);
}
DWORD end = timeGetTime();

std::cout << "start:" << start << ",end:" << end << "," << (end - start) << "ms" << std::endl;
}

if((DWORD)&rets <= 0xffff){
MessageBox((HWND)&rets, nullptr, nullptr, MB_OK);
}

timeEndPeriod(1);
return 0;
}

2417774さん:2010/07/20(火) 18:05:28
std::listとかってどれくらい遅いのだろうか・・・

2418774さん:2010/07/20(火) 18:08:50
仕様を読んでないのがいけないのだろうが、イテレータって持続時間どれだけなんだろうか。
勿論、その要素自体を削除したらそれまでなのは理解できるが、他の要素についてのイテレータは何時まで持つのか。
仕様で規定されているのだろうか。

2419774さん:2010/07/20(火) 19:06:19
Variadic templatesが既に実装されていただと・・・

2420774さん:2010/07/20(火) 19:07:53
遊ぶしか無いではないか。
取り敢えず、Wikipediaの例をコピペしてみる。

2421774さん:2010/07/20(火) 19:10:08
Wikipediaの情報古いな。

2422774さん:2010/07/20(火) 19:20:41
多分。

2423774さん:2010/07/20(火) 21:06:12
ものすごく利用できそうなのに、何も思いつかない。
テスト勉強をしろということか。

2424774さん:2010/07/20(火) 21:22:10
ココを押えておけばCSS3がだいたい分かるツール集 | 日刊ウェブログ式
http://toshiiy.blog22.fc2.com/blog-entry-112.html
-----
ベンダーコードを付けないといけない理由が理解出来ない。

2425774さん:2010/07/20(火) 21:42:11
なぜ,/var や /etc が /etc や /cfg というディレクトリ名ではないのか? - NO!と言えるようになりたい
http://d.hatena.ne.jp/ytakano/20100715/1279219401

2426774さん:2010/07/20(火) 21:50:40
Google JavaScript Style Guide 和訳 &mdash; Google JavaScript Style Guide 和訳 v0.1 documentation
http://cou929.nu/data/google_javascript_style_guide/
-----
自分は関数名の初めは大文字にする派。
クラスの最初の文字は、Cとかにするかもしれない。大抵はしないが。

2427774さん:2010/07/20(火) 22:03:53
さっきまで、どうしてpop_back()がないのか、とかアホなことを思っていた。
そりゃ、無いわ。

2428774さん:2010/07/20(火) 22:04:47
違う。
どうして、pop_back()の時に元々一番最後の要素を何故返さないのか?ということを疑問に思っていたが、そりゃ返さない方がいいに決まっているだろう、ということが今わかった。

2429774さん:2010/07/20(火) 22:05:48
でも、std::vector<T>のTがint,char,int*,char*...etc.だったら返して欲しいなあ。

2430774さん:2010/07/20(火) 22:06:52
back(),front()を使えと言っているのは分かります。
しかし、タイプ量が(ry

2431774さん:2010/07/20(火) 22:14:22
Standard Template Library Programmer's Guide
http://www.sgi.com/tech/stl/

2432774さん:2010/07/20(火) 22:32:28
std::list::iteratorを使った走査はポインタを利用してるだけあって早いな。
十分1ms以下で行える(100000個)。
ちなみに10000000個でやったら平均50msぐらい。

2433774さん:2010/07/20(火) 22:41:00
100000000個にしたら、予想通りメモリが足りなかった。(32bits)
64bitsにしたら、動いた。
恐らく、動作終了後物理メモリは綺麗になっただろう(笑)
結局、77184msかかっている。
かかりすぎである。

2434774さん:2010/07/20(火) 23:18:40
どっかの誰かが、C++でソース中にdeleteが出てくるのがおかしい、と言っていました。
確かにその通りだよな。速度を優先していないならば。
どうでもいいが、std::list<std::unique_ptr<T>>って結構使えるんじゃね?

2435774さん:2010/07/20(火) 23:35:47
std::list<std::auto_ptr<T>>だし。

2436774さん:2010/07/20(火) 23:40:09
C++0xでunique_ptrが新しく出来るのだが、所有権の移動がstd::move(正確には右辺値参照?)で行われるらしい。
std::list<unique_ptr<T>>は利用出来るのかな?

2437774さん:2010/07/20(火) 23:47:39
-----
>なのでもちろんstd::vectorには入れられません。
>しかしこういうときはstd::shared_ptrを使うので問題ありませんね。
-----
明らかにlist中でしかメモリ確保しない場合にはオーバースペックすぎるだろ。

2438774さん:2010/07/20(火) 23:53:46
日記帳だ! with Tux on Libserver :: 破壊的コピーは速かった、unique_ptrも速かった
http://hdmr.org/d/?e=483
-----
このページのサンプルソースはバグを孕んでいる(らしい)。
-----
[迷信] アルゴリズム関数内で関数オブジェクトはコピーされない | 株式会社きじねこ
http://www.kijineko.co.jp/tech/superstitions/functor-is-not-copied-in-algorithm.html

2439774さん:2010/07/20(火) 23:55:48
是非ともstd::vector<>,std::list<>系のSTLの.push_back()やらの要素追加系の関数は、右辺値参照(だったか?)をとるようにして欲しい、と言うかなっているだろう。
なっていなかったら幻滅である。なっていないならば、俺の予想を超越する駄目な理由があるだろう(笑)

2440774さん:2010/07/21(水) 00:13:30
仕様に当たろう。
それが一番確実である。

2441774さん:2010/07/21(水) 00:21:43
// 23.3.4.3 modifiers:
template <class... Args> void emplace_front(Args&&... args);
void pop_front();
template <class... Args> void emplace_back(Args&&... args);
void push_front(const T& x);
void push_front(T&& x);
void push_back(const T& x);
void push_back(T&& x);
void pop_back();

2442774さん:2010/07/21(水) 00:22:37
おお、直接コンストラクタまで呼び出せるemplace_back(front)まで用意されているぜ!
折角だから、俺はemplace_backを使うぜ!

2443774さん:2010/07/21(水) 00:23:50
正直、これぐらいしか、なんとかtemplateは使いどころがない。

2444774さん:2010/07/21(水) 00:24:46
つまり、>>2437は嘘である。
因みに、>>2437>>2438と同じサイト。

2445774さん:2010/07/21(水) 00:25:26
>>2444は多分。
まだ検証していない。

2446774さん:2010/07/21(水) 00:32:46
一発でコンパイルが通らなかった&長すぎで読む気にならない。

2447774さん:2010/07/21(水) 00:33:59
あ、通ったらびっくり。
多態性で遊ぼうと思ったのに、interfaceを継承していないもん。

2448774さん:2010/07/21(水) 00:37:31
__func__の定義を読んでいないので、正確にはなんとも言えないのだが、gccでは、クラス名が表示されない。
CClass::CClass(int)中で__func__とやってもCClassとしか表示されないのがgcc。
独自拡張でもいいから、CClass::CClassとだして欲しい。あわよくば、CClass::CClass(int)。
へ?__LINE__使えって?

2449774さん:2010/07/21(水) 00:41:06
デストラクタが呼ばれないと思ったら、デストラクタを仮想化してなかった。
怖い怖い。

2450774さん:2010/07/21(水) 00:43:23
あれ、純仮想デストラクタって出来ないのか・・・?
細かいところ勉強不足だなあ。

2451774さん:2010/07/21(水) 00:44:00
というか、純粋(ryなのか。

2452774さん:2010/07/21(水) 00:44:33
まあ、つまらないサンプル。
-----

#include <iostream>
#include <windows.h>
#include <list>
#include <memory>

#define nullptr NULL

class ITest{
public:
virtual auto Show()->void = 0;
virtual ~ITest(){
}
};

class CTest1 : public ITest{
private:
int m_num;

public:
CTest1(int num)
: m_num(num)
{
std::cout << "CTest1::CTest1(int)" << std::endl;
}
virtual ~CTest1(){
std::cout << "CTest1::~CTest1()" << std::endl;
}

virtual auto Show()->void{
std::cout << "CTest1," << m_num << std::endl;
}
};
class CTest2 : public ITest{
private:
double m_num;

public:
CTest2(double num)
: m_num(num)
{
std::cout << "CTest2::CTest2(double)" << std::endl;
}
virtual ~CTest2(){
std::cout << "CTest2::~CTest2()" << std::endl;
}

virtual auto Show()->void{
std::cout << "CTest2," << m_num << std::endl;
}
};

auto WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/)->int{
timeBeginPeriod(1);
{
std::list<std::unique_ptr<ITest>> ls;
ls.emplace_back(new CTest1(100));
ls.emplace_back(new CTest2(100.));
}
timeEndPeriod(1);
return 0;
}

2453774さん:2010/07/21(水) 00:45:40
>>2452
勿論動くサンプルです。
全然unique_prtが動かないことはないです。

2454774さん:2010/07/21(水) 00:50:13
上のサイトによれば、unique_ptrはほぼ生のポインタと同コストのようなのでこれはかなり使える。と思う。

2455774さん:2010/07/21(水) 00:55:00
某所で、
std::vector<int*> vec;
vec.push_back(new int(100));//ここ危ない。
という話があった。push_back関数内で例外が投げられた時に、newで確保されたメモリが開放されないと。

2456774さん:2010/07/21(水) 00:55:32
>>2455
は違う。

2457774さん:2010/07/21(水) 00:55:59
std::shared_ptr<int> p(new int);
だよ!

2458774さん:2010/07/21(水) 00:56:48
俺が使う範囲ではshared_ptr&weak_ptrはオーバースペックだろう。

2459774さん:2010/07/21(水) 00:59:48
大体、上に書いたソースを読めば、俺がC++を使いこなしていないことが良く分かる。
普通にstd::for_each使えばいいのにね。

2460774さん:2010/07/21(水) 01:19:38
コンテナ系STLを最適化するんだったら、アロケータを自分で作ったほうがいいのか?

2461774さん:2010/07/21(水) 01:20:32
3986 :774さん:2010/07/21(水) 01:01:32
std::for_each(ls.begin(), ls.end(), [](std::unique_ptr<ITest> &p){
p->Show();
});
ん・・・。
これは普通にiteratorで書いたほうがいいか・・・

3987 :774さん:2010/07/21(水) 01:14:54
ちゃんとlist::eraseで消しても、デストラクタが呼ばれるし、他のイテレータも有効だなあ。
イテレータの件については標準なのか調べてみる。明日、テストだし寝る。
-----
#include <iostream>
#include <windows.h>
#include <list>
#include <memory>
#include <algorithm>

#define nullptr NULL

class ITest{
public:
virtual auto Show()->void = 0;
virtual auto IsEven()->bool = 0;
virtual ~ITest(){
}
};

class CTest1 : public ITest{
private:
int m_num;

public:
CTest1(int num)
: m_num(num)
{
std::cout << "CTest1::CTest1(int)" << std::endl;
}
virtual ~CTest1(){
std::cout << "CTest1::~CTest1(), m_num = " << m_num << std::endl;
}

virtual auto Show()->void{
std::cout << "CTest1::Show(), m_num = " << m_num << std::endl;
}
virtual auto IsEven()->bool{
return !static_cast<bool>(m_num & 1);
}
};
class CTest2 : public ITest{
private:
double m_num;

public:
CTest2(double num)
: m_num(num)
{
std::cout << "CTest2::CTest2(double)" << std::endl;
}
virtual ~CTest2(){
std::cout << "CTest2::~CTest2(), m_num = " << m_num << std::endl;
}

virtual auto Show()->void{
std::cout << "CTest2::Show(), m_num = " << m_num << std::endl;
}
virtual auto IsEven()->bool{
return !static_cast<bool>(static_cast<int>(m_num) & 1);
}
};

auto WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/)->int{
std::list<std::unique_ptr<ITest>> ls;
for(int i = 0; i < 10; ++i){
ls.emplace_back(new CTest1(i));
ls.emplace_back(new CTest2(static_cast<double>(i)));
}

for(auto itn = ls.begin(), it = itn++ , end = ls.end(); it != end; it = itn, ++itn){
if((*it)->IsEven()){
ls.erase(it);
}
}

return 0;
}

3988 :774さん:2010/07/21(水) 01:17:09
g++ main.cpp -std=c++0x -O3 -lwinmm -m32

2462774さん:2010/07/21(水) 01:25:35
C++編(標準ライブラリ) 第28章 アロケータ
http://www.geocities.jp/ky_webid/cpp/library/028.html
---
>のように書きますが、この場合、独自のアロケータCMyAllocatorが確保する型はint型な訳です。つまり、int型用 のアロケータなので、各要素を表現する構造体の型とは一致するはずがありません。従って、std::listは、プログラマ がせっかく定義したアロケータを使うことがないことになります。
>これはstd::setやstd::mapのような連想コンテナ全般にも当てはまることです。これらは、ほとんどの実装では、 木構造(アルゴリズムとデータ構造編第16章参照)を使っているので、 リスト構造の場合と同様の理由で、指定したアロケータが使用できないことになります。
-----
な、なんだってー。
まあ、詳しくは実装を見てみないと分からないが、何のために
-----
// アロケータをU型にバインドする
template <class U>
struct rebind
{
typedef allocator<U> other;
};
-----
があるのかが分からない。

2463774さん:2010/07/21(水) 01:37:55
パッと見、rebind使っているから効果はあると思う。

2464774さん:2010/07/21(水) 09:38:52
g++ main.cpp -std=c++0x -O3 -lwinmm -m32

2465774さん:2010/07/21(水) 09:46:48
何故上のようなことを調べたかというと、listの中の要素に自身のiteratorを持たせて、削除も定数時間で行えるようにしたかったからです。
ただそれだけ。
iteratorについては帰ってきてから、仕様を当たる。
そういう記述はない気がする。

2466774さん:2010/07/21(水) 10:04:34
forward_list発見・・・

2467774さん:2010/07/21(水) 10:09:09
ちゃんと前に読んだことが有るはずなのに、忘れていた。
C言語で書かれたのと同じスピードで動くように簡素化されているんだよね。

2468774さん:2010/07/21(水) 10:14:29
iterator before_begin();
const_iterator before_begin() const;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;

2469774さん:2010/07/21(水) 10:17:13
取り敢えず、forward_listは俺の需要を満たすものではない。
list最高!

2470774さん:2010/07/21(水) 17:42:55
>listにデータ操作を加えた後は、それ以前に取得したイテレータの動作は保証
>されないと思います。
>例えば、ソートや、データの追加、削除を行った場合。
-----
一番困るのが、仕様に書かれていないということだ。
ちゃんと、保証しなければならないor保証しなくても良いと書いておくべきだ。
勿論、書いてあるかすら確認していないので変なことを俺は言っているかもしれない。
上が正しいならば、走査しながらの削除が出来ないとは困ったものだ。

2471774さん:2010/07/21(水) 17:44:12
STLはそういうことはremove_ifを使ってやれと言っているのだろうか。
分からんでもないが・・・
俺が書こうとしているソースを考えると、かなり意味論的におかしい。
実行は出来るが。

2472774さん:2010/07/21(水) 17:44:41
まあ、こっちの方がメモリを食わなくてうれしいかもしれない

2473774さん:2010/07/22(木) 03:09:06
俺はなんとアホなんだ。
自分の要求を満たすlistを作ればいいじゃないか。

2474774さん:2010/07/22(木) 03:35:38
駄目だ。
仕様がデカすぎで面倒。

2475774さん:2010/07/22(木) 05:52:15
WinGDI遅すぎ。

2476774さん:2010/07/22(木) 23:46:43
何かやらかしたいなと思うのだが、やっぱり先人には敵わない。
俺はただの凡人だなあと思う限りである。

2477774さん:2010/07/23(金) 00:14:14
Greasemonkey Script : ニコニコ動画に拡張マイリストを追加するGreasemonkeyスクリプト - 棚からパルチャギ
http://castor.s26.xrea.com/products/greasemonkey/nicovideo_additional_mylist.html
-----
のSeaHorse版が全く更新されていない。
まあ、人口が少ないので仕方ないだろう。俺も最近RSSリーダーになっているし。
早くIE9出ろ。
アレで、ようやくFx2辺りに並ぶ。

2478774さん:2010/07/23(金) 01:09:23
JS+Javaで作りたくなった。
徹夜で作ってみせる!
まあ、Javaは初めてなので、上手くいかなさそう。

2479774さん:2010/07/23(金) 01:20:55
いきなり頓挫しそうだぜ!
取り敢えず明日の朝食を食うために、寝たほうがいいかなあ

2480774さん:2010/07/23(金) 01:40:52
有限不実行、これが俺。
駄目駄目だなあ・・・

2481774さん:2010/07/23(金) 01:41:15
まあ、ゆっくりやろう。
今日はまだ二十二時間あるのだ。

2482774さん:2010/07/23(金) 10:18:32
正直、Sleipnirなんてどうでもいいので、適当にGoogle Chromeのプラグインでも作ってみたいが、ちょっと他にやりたいことが出来たのでそれをやる。

2483774さん:2010/07/23(金) 10:28:28
#include <iostream>
#include <windows.h>

#define nullptr NULL

//関数
auto WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)->int;
auto CleanMessage(int *ret)->bool;
auto CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)->LRESULT;

//実装
auto WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)->int{
WNDCLASSEX wc = {sizeof(wc)};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
wc.lpszMenuName = nullptr;
wc.lpszClassName = TEXT("AA");
wc.hIconSm = nullptr;

ATOM aWnd = RegisterClassEx(&wc);
if(aWnd == INVALID_ATOM){
return -1;
}

//ウィンドウの大きさの計算 横:600 縦;300
const int clientwidth = 800;
const int clientheight = 600;
const int screenx = GetSystemMetrics(SM_CXSCREEN);
const int screeny = GetSystemMetrics(SM_CYSCREEN);

RECT windowRect;
windowRect.left = screenx / 2 - clientwidth / 2;
windowRect.right = screenx / 2 + clientwidth / 2;
windowRect.top = screeny / 2 - clientheight / 2;
windowRect.bottom = screeny / 2 + clientheight / 2;

AdjustWindowRectEx(&windowRect, WS_CAPTION | WS_SYSMENU, FALSE, 0);

HWND hWnd = CreateWindowEx(
0,
reinterpret_cast<LPCTSTR>(aWnd),
TEXT("WindowTitle!!"),
WS_CAPTION | WS_SYSMENU,
windowRect.left, windowRect.top,
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
nullptr,
nullptr,
hInstance,
nullptr
);
if(hWnd == nullptr){
return -2;
}

ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);


static const DWORD waitTimes[] = {
16, 17, 17
};
int index = 0;
int retValue;
HDC hdcWin = GetDC(hWnd);
HDC hdcMem = CreateCompatibleDC(hdcWin);
HBITMAP hBitmapMem = CreateCompatibleBitmap(hdcWin, clientwidth, clientheight);
SelectObject(hdcMem, hBitmapMem);
DWORD old = timeGetTime();
int i = 0;

timeBeginPeriod(1);
for(;;){
if(CleanMessage(&retValue)){
break;
}

//ただただ面倒臭い処理
{
RECT rc;
rc.left = 0;
rc.right = clientwidth;
rc.top = 0;
rc.bottom = clientheight;
FillRect(hdcMem, &rc, reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)));
int j = 0;

BitBlt(hdcWin, 0, 0, clientwidth, clientheight, hdcMem, 0, 0, SRCCOPY);
}

std::cout << timeGetTime() - old << std::endl;

if(CleanMessage(&retValue)){
break;
}

2484774さん:2010/07/23(金) 10:28:39

//時間処理
{
DWORD now = timeGetTime();
DWORD diff = now - old;
if(diff < waitTimes[index]){
DWORD sleeptime = waitTimes[index] - diff;
if(sleeptime >= 5){
Sleep(sleeptime - 3);
}
while(timeGetTime() - old < waitTimes[index]);
}
old = timeGetTime();
if(++index >= sizeof(waitTimes) / sizeof(waitTimes[0])){
index -= sizeof(waitTimes) / sizeof(waitTimes[0]);
}
}
}
timeEndPeriod(1);

DeleteObject(hBitmapMem);
DeleteObject(hdcMem);
ReleaseDC(hWnd, hdcWin);

return retValue;
}

auto CleanMessage(int *ret)->bool{
MSG msg;
bool flag = false;
while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)){
if(msg.message != WM_QUIT){
TranslateMessage(&msg);
DispatchMessage(&msg);
}else{
*ret = msg.wParam;
flag = true;
}
}
return flag;
}

auto CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)->LRESULT{
switch(msg){
case WM_DESTROY:{
PostQuitMessage(0);
break;
}

default:{
return DefWindowProc(hWnd, msg, wp, lp);
}
}

return 0;
}

2485774さん:2010/07/23(金) 11:09:32
SDLが通らない。
調べたサイトの対策を講じてみても動かない。
SDLを自分でコンパイルしろということですね分かります。

2486774さん:2010/07/23(金) 11:11:30
シェルスクリプト入ってねーよwwww

2487774さん:2010/07/23(金) 11:23:11
あれ、普通に-lmingw32で通った。
さっきは通らなかった気がするのに・・・

2488774さん:2010/07/23(金) 11:29:24
37行程度のソースを一回で通せないとは・・・

2489774さん:2010/07/23(金) 11:34:27
俺が外出している間に勝手にSDL_imageがコンパイル出来てないかな?

2490774さん:2010/07/23(金) 14:20:19
勿論出来ているはずもなく。
makeが上手くいかない・・・

2491774さん:2010/07/23(金) 14:22:40
Cygwinは入れたくない。

2492774さん:2010/07/23(金) 14:57:24
普通にVC用のlibいれたら行けた。なんぞそれ。

2493774さん:2010/07/23(金) 15:40:42
#include <iostream>
#include <list>
#include <memory>
#include <algorithm>
#include <random>
#include <ctime>
#include <cmath>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

#define nullptr NULL

class IShot{
public:
virtual bool Move() = 0;
virtual void Show(SDL_Surface *screen, SDL_Surface *image) = 0;
virtual bool HitTest() = 0;
};

class CShotLine : public IShot{
public:
virtual bool Move(){
m_x += m_v * std::sin(m_rad);
m_y += m_v * std::cos(m_rad);
if(m_x < 0 || m_x > 600 || m_y < 0 || m_y > 300){
return false;
}
return true;
}
virtual void Show(SDL_Surface *screen, SDL_Surface *image){
SDL_Rect rc;
rc.x = m_x;
rc.y = m_y;
SDL_BlitSurface(image, nullptr, screen, &rc);
}
virtual bool HitTest(){
return false;
}

CShotLine(int x, int y, int v, double rad)
: m_x(x), m_y(y), m_v(v), m_rad(rad)
{}

private:
double m_x, m_y;
int m_v;
double m_rad;
};

//関数
int main(int argc, char **argv){
if(SDL_Init(SDL_INIT_VIDEO) < 0) return -1;

SDL_WM_SetCaption("TEST", NULL);

SDL_Surface *screenSurface;
screenSurface = SDL_SetVideoMode(600, 300, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

SDL_Surface *image = IMG_Load("shot.png");
std::list<std::unique_ptr<IShot>> shots;
std::mt19937 engine(static_cast<unsigned int>(std::time(nullptr)));
unsigned int i = 0;

for(;;){
{
SDL_Rect dest;
dest.x = 0;
dest.y = 0;
dest.w = 600;
dest.h = 480;
SDL_FillRect(screenSurface, &dest, 0x00000000);
}

shots.emplace_back(new CShotLine(engine() % 600, engine() % 100, engine() % 2 + 1, (double)i++ / 200));

shots.erase(std::remove_if(shots.begin(), shots.end(), [](std::unique_ptr<IShot> &b){return !b->Move();}), shots.end());
std::for_each(shots.begin(), shots.end(), [&](std::unique_ptr<IShot> &b){b->Show(screenSurface, image);});

SDL_Flip(screenSurface);

SDL_Event ev;
while(SDL_PollEvent(&ev)){
switch(ev.type){
case SDL_QUIT:{
return 0;
}
case SDL_KEYDOWN:{
SDLKey *key = &ev.key.keysym.sym;
if(*key == 27){
return false;
}
break;
}
}
}
}

SDL_FreeSurface(image);
SDL_Quit();
return 0;
}

2494774さん:2010/07/23(金) 15:46:51
>Note: 少くとも10ミリ秒の遅延を考えて下さい。 プラットフォームによってはもっと短かい時間の場合もありますが、この値が最も一般的です。
-----
つまり、whileでループを回せということですね。分かります。

2495774さん:2010/07/23(金) 15:48:49
60fpsで動かしているのにかくかく。
スペックは余裕のはずである。

2496774さん:2010/07/23(金) 16:12:24
毎フレーム3px動くだけでかなり早い。
まあ、一秒で180pxも動くし。

2497774さん:2010/07/23(金) 16:59:09
糞ゲー出来た!

2498774さん:2010/07/23(金) 20:01:55
上手く動作しない。
繰り返しなのに、繰り返してない。
コンパイラ・・・

2499774さん:2010/07/23(金) 20:03:12
しかし、今までコンパイラのバグだと思っていたものが、やっぱり俺のミスだったので、今回もそうである気がする。

2500774さん:2010/07/23(金) 20:11:43
以下のソースが上手く動かない・・・
-----
class CShotLineSin : public IShot{
public:
virtual bool Move(){
double A = m_A * std::sin(m_frame * m_omega);
m_x += m_vx;
m_y += m_vy;
m_tx = m_x + A * m_cos;
m_ty = m_y - A * m_sin;
if(m_x < -10 - m_A || m_x > screen_width + 10 + m_A || m_y < -10 - m_A || m_y > screen_height + 10 + m_A){
return false;
}
m_frame++;
return true;
}
virtual void Show(SDL_Surface *screen){
SDL_Rect rc;
rc.x = static_cast<int>(m_tx) - 7;
rc.y = static_cast<int>(m_ty) - 7;
SDL_BlitSurface(m_image, nullptr, screen, &rc);
}
virtual bool HitTest(int x, int y){
int dif_x = m_tx - x;
int dif_y = m_ty - y;
if(dif_x * dif_x + dif_y * dif_y < 3 * 3){
return true;
}
return false;
}

CShotLineSin(int x, int y, double v, double rad, double A, double omega, SDL_Surface *image)
: m_x(x), m_y(y), m_tx(x), m_ty(y), m_sin(std::sin(rad)), m_cos(std::cos(rad)), m_vx(v * m_sin), m_vy(v * m_cos), m_A(A), m_omega(omega), m_image(image), m_frame(0)
{}

private:
double m_x, m_y;
double m_tx, m_ty;
double m_vx, m_vy;
double m_sin, m_cos;
double m_A;
double m_omega;
unsigned int m_frame;
SDL_Surface *m_image;
};

2501774さん:2010/07/23(金) 20:19:01
std::list::sizeってO(1)でいいのか?

2502774さん:2010/07/23(金) 20:20:57
でいいみたい。


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板