[PloobsEngine] Tutorial 1 – Components and Input System


This second tutorial will teach you about the PloobsEngine Components and introduce the  Input handler System. (tutorials series here)

The idea is to make a little introduction describing the Components design, after show how the Input handler works and finish with a code sample.

What the hell are the PloobsEngine Components ?

Components are an abstraction to funcionalities that should be global to all screens everywhere. Its was designed to be completely independent and pluggable. To accomplish this task we used a slightly modified version of the Design Pattern Command Processor.

Every component extends the abstract class IComponent. You only communicate with components sending Commands objects through the CommandProcessor to them. The components contact our objects using specifics callbacks. Every Component used must be registered before, the PloobsEngine automatically register the Input and the DebugRender Components others are user responsability to register.

Remember, this is very important: Components are global, they are not binded to screen.

The CommandProcessor is a static class that is responsible to deliver Commands to the right component. It can send a command syncronous (the command is send exactely when the function is called) or assyncronous (the engine will send  the command as soon as possible, ALWAYS PREFFER THIS METHOD OF SENDING COMMANDS, IF YOU CAN — this method does not use threads)

As said, before using a component you need to add them, when you dont need it anymore you can remove

To add a Component just use this (we normally add components in the Initialize method of the IScreen, it has a parameter called EngineStuff that you use to add/remove and check if a component exists):

COMPONENT COMP = new COMPONENT();
engine.addcomponent(COMP);

Where COMPONENT is the actual component. After this we can send commands.

To send a Commmand, just use:

CommandProcessor.getCommandProcessor().SendCommandAssyncronous(COMMAND);

or

CommandProcessor.getCommandProcessor().SendCommandSyncronous(COMMAND);

 

The input advanced Component

This component is reponsible for handling Keyboard and Mouse. You send a command to this component describing an event (like Key B being pressed or Key O released) and the component will call a callback when the event happens (the process of associating a key event to a callback is called binding in the engine).

The input advanced component recieves the following commands:

  • ClearInputsCommand -> CLEAR ALL THE BINDINGS
  • BindMouseCommand -> BIND A MOUSE HANDLER
  • BindKeyCommand -> BIND A KEYBOARD HANDLER
  • TurnOffInputMaskCommand -> TURN OF AN INPUT MASK
  • TurnOnInputMaskCommand -> TURN OF AN INPUT MASK

The BindKeyCommand for example recieve two parameters, the first is an object called SimpleConcreteKeyboardInputPlayable that describes teh key event and the callback to call when the event is fired. The second is the action (add or remove the event). BindMouseCommand works in a similar way.

We can separate the inputs events (key and mouse handlers) in groups and enable and disable them when needed. A simple example is when we want to disable all character inputs when we enter in a in game menu (just put the inputs in diferrent groups and enable/disable them when needed).

To define the groups we use an InputMask (whe can pass it as a parameter in the SimpleConcreteKeyboardInputPlayable for example). It is a bit field. The engine has a active InputMask, if it input mask matchs with your event InputMask.

One example make everything clear:

Suppose that the engine has the 101 inputmask active.

And suppose that we bind 2 key events, the first has the input mask 100 and the second has 010.

Every frame The engine will check its Inputmask againt the key handlers input mask.

This is done by bit. The 101 in the engine InputMask means that the group 100 and the goup 001 are on and the 010 is off.

So, only the first handler will have the chance to be activated (the engine first check the InputMask of the registered event handler, if successful, it checks if the event really needs to be fired)

Internaly (if you are curious to know =P) the engine does this calculation: 101 ^ 100 = 100 Activate (100 = 100) for the first event handler and 101 ^ 010 != 101 (010 != 101) Not Activate for the second.

You can change the engine InputMask using TurnOffInputMaskCommand and TurnOnInputMaskCommand (you can use bit field operation to set the mask)

There are some special InputMasks like GALL that is 11111111111 (default in engine — means that all groups are enabled)

GSYSTEM is a very special inputmaks, cause it CANT be turned off (even if you try), if you bind a key handler to it, it will have the chance to be fired always.

The ClearInputsCommand, as the name said, clears ALL the event handlers =P.

An example of registering a event handler is:

SimpleConcreteKeyboardInputPlayable ik4 = new SimpleConcreteKeyboardInputPlayable(StateKey.DOWN, new Keys[] { Keys.LeftControl, Keys.U }, Multiple);
BindKeyCommand bk = new BindKeyCommand(ik4, BindAction.ADD);
CommandProcessor.getCommandProcessor().SendCommandAssyncronous(bk);

We created the SimpleConcretekeyboardInputPlayable passing the state of the key, the Keys (for Combo, you can use a single key if you want) and the Callback. After we create the command and send it using the Command Processor (we used the default InputMask GSYSTEM).

The callback is a function with the following signature:

public void Multiple(InputPlayableKeyBoard ipk)
{
/// Handle the event =P
}

There lots of ways to create the SimpleConcretekeyboardInputPlayable (dont set the event on the construtore, use the property to do this, it is easier =P)

REMEMBER, COMPONENTS ARE GLOBAL, the binding will remains until you delete it.

BUT, sometimes, we want to bind the inputs for just one screen, when the screen goes away, we want to remove the bindings (it is boring to override the clean up method of the screen to done this …). So the engine provides an alternate solution, instead of sending the commands directely to the input component, you can use the method BindInput of the IScreen to does the job.

SimpleConcreteKeyboardInputPlayable ik2 = new SimpleConcreteKeyboardInputPlayable(StateKey.PRESS, Keys.Y, g2,InputMask.G2);
this.BindInput(ik2);

In this case we “atached” the SimpleConcretekeyboardInputPlayable to the screen, that will take care of makind the binding and removing it when the screen goes away. (look, in this case we used the G2 InputMask — this is not a special mask, can be used for anything). The binding made this way can be removed before the screen goes away, just call the method RemoveInputBinding()

 

Code Example

The following code sample show how to use the InputAvanced. The event key T Pressed is binded to the InputMask G1, the event key Y Pressed is binded to the InputMaks G2 and the Key Space is binded to the GSystem (always active).

When you press Space you change the engine active InputMask to G1 and G2 (and you see that Key T Pressed does not work when G1 is active)

There is also a binding showing how to use the Combos.

The code is:

using PloobsEngine.SceneControl;
using PloobsEngine.Physics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Input;
using Microsoft.Xna.Framework;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.Modelo;
using PloobsEngine.Material;
using PloobsEngine.Commands;
using PloobsEngine.Light;
using Microsoft.Xna.Framework.Input;

namespace IntroductionDemo4._0
{
    ///
    /// InputScreen
    ///
    public class KeyboardInputScreen: IScene
    {
        ICamera cam;        

        protected override void SetWorldAndRenderTechnich(out IRenderTechnic renderTech, out IWorld world)
        {
            world = new IWorld(new BepuPhysicWorld(-0.097f,true), new SimpleCuller());
            DeferredRenderTechnicInitDescription desc = DeferredRenderTechnicInitDescription.Default();
            desc.DefferedDebug = false;
            desc.UseFloatingBufferForLightMap = false;
            renderTech = new DeferredRenderTechnic(desc) ;
        }
        protected override void  LoadContent(PloobsEngine.Engine.GraphicInfo GraphicInfo, PloobsEngine.Engine.GraphicFactory factory, IContentManager contentManager)
        {
            base.LoadContent(GraphicInfo, factory, contentManager);

            #region Models

            {
                SimpleModel sm = new SimpleModel(factory,"..\\Content\\Model\\cenario");
                IPhysicObject pi = new TriangleMeshObject(sm,Vector3.Zero, Matrix.Identity,Vector3.One,MaterialDescription.DefaultBepuMaterial());
                DeferredNormalShader shader = new DeferredNormalShader();
                shader.SpecularIntensity = 0;
                shader.SpecularPower = 0;
                IMaterial mat = new DeferredMaterial(shader);
                IObject obj3 = new IObject(mat, sm, pi);
                this.World.AddObject(obj3);
            }

            #endregion

            cam = new CameraFirstPerson(GraphicInfo.Viewport);
            cam.FarPlane = 3000;

            #region NormalLight
            DirectionalLightPE ld1 = new DirectionalLightPE(Vector3.Left, Color.White);
            DirectionalLightPE ld2 = new DirectionalLightPE(Vector3.Right, Color.White);
            DirectionalLightPE ld3 = new DirectionalLightPE(Vector3.Backward, Color.White);
            DirectionalLightPE ld4 = new DirectionalLightPE(Vector3.Forward, Color.White);
            DirectionalLightPE ld5 = new DirectionalLightPE(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            this.World.AddLight(ld1);
            this.World.AddLight(ld2);
            this.World.AddLight(ld3);
            this.World.AddLight(ld4);
            this.World.AddLight(ld5);
            #endregion

            this.World.CameraManager.AddCamera(cam);            

            ///Bind a Key event (combination of Key + state(pressed, Released ...) + inputMask ) to a function
            SimpleConcreteKeyboardInputPlayable ik1 = new SimpleConcreteKeyboardInputPlayable(StateKey.PRESS, Keys.T, g1, InputMask.G1);
            ///When you use the method Bind of a IScreen, The key event will be sent by the engine while this screen remains added in the ScreenManager.
            ///TO create a Gloal Input (Keep working even if the screen goes away), see the DemosHomeScreen.cs
            this.BindInput(ik1);            

            SimpleConcreteKeyboardInputPlayable ik2 = new SimpleConcreteKeyboardInputPlayable(StateKey.PRESS, Keys.Y, g2,InputMask.G2);
            this.BindInput(ik2);            

            ///The SYSTEM Mask is Always On (cant be turned off)
            SimpleConcreteKeyboardInputPlayable ik3 = new SimpleConcreteKeyboardInputPlayable(StateKey.PRESS, Keys.Space, ChangeGroup,InputMask.GSYSTEM);
            this.BindInput(ik3);            

            ///StateKey.DOWN mean when the key is down the event will be fired --looooots of times(samae as UP)
            ///StateKey.PRESS is fired ONCE when the key is pressed (same as RELEASE)
            ///WHEN USING COMBOS, use DOWN AND UP (better for precision)
            ///The parameter EntityType is not used internaly
            SimpleConcreteKeyboardInputPlayable ik4 = new SimpleConcreteKeyboardInputPlayable(StateKey.DOWN, new Keys[] { Keys.LeftControl, Keys.U }, Multiple);
            this.BindInput(ik4);

            ///Send a command (design pattern) to the InputSystem to change the InputMask
            TurnOnInputMaskCommand tom = new TurnOnInputMaskCommand(InputMask.GALL);
            CommandProcessor.getCommandProcessor().SendCommandAssyncronous(tom);

            isAllActive = true;

            this.RenderTechnic.AddPostEffect(new AntiAliasingPostEffect());
        }

        bool isAllActive;
        bool isGroup1;
        bool isGroup2;
        bool isChangeGroup;
        bool isComboPressed;

        protected override void  Draw(GameTime gameTime, RenderHelper render)
        {
 	        base.Draw(gameTime, render);

            render.RenderBegin(Matrix.Identity);
            render.RenderText("Demo: Keyboard Input", new Vector2(GraphicInfo.Viewport.Width - 515, 15),Vector2.One ,Color.White);
            render.RenderText("Press Space to change the Active Input Mask (G1 or G2)", new Vector2(GraphicInfo.Viewport.Width - 515, 40), Vector2.One, Color.White);
            render.RenderText("Press T to use a G1 InputMask Input", new Vector2(GraphicInfo.Viewport.Width - 515, 60), Vector2.One, Color.White);
            render.RenderText("Press Y to use a G2 InputMask Input", new Vector2(GraphicInfo.Viewport.Width - 515, 80), Vector2.One, Color.White);
            render.RenderText("Press Ctrl + U TO use a Combo (Registered in all Masks)", new Vector2(GraphicInfo.Viewport.Width - 515, 100), Vector2.One, Color.White);
            if(isAllActive)
                render.RenderText("Group ALL Active", new Vector2(20, 40),Vector2.One, Color.White);
            if (isGroup1)
                render.RenderText("Group1", new Vector2(20, 20), Vector2.One, Color.White);
            if(isGroup2)
                render.RenderText("Group2", new Vector2(100, 20),Vector2.One, Color.White);
            if(isChangeGroup)
                render.RenderText("Active InputMask " + Groups[index], new Vector2(20, 40),Vector2.One, Color.White);
            if(isComboPressed)
                render.RenderText("Combo Pressed", new Vector2(20, 60),Vector2.One, Color.White);
            render.RenderEnd();

        }

        public void g1(InputPlayableKeyBoard ipk)
        {
            isGroup2 = false;
            isComboPressed = false;
            isGroup1 = true;
        }
        public void g2(InputPlayableKeyBoard ipk)
        {
            isGroup1 = false;
            isComboPressed = false;
            isGroup2 = true;
        }

        InputMask[] Im = new InputMask[] { InputMask.G1, InputMask.G2, InputMask.GALL };
        string[] Groups = new string[] { "G1", "G2", "GALL" };
        int index = 2;
        public void ChangeGroup(InputPlayableKeyBoard ipk)
        {
            index = (index + 1) % 3;

            ///Turn Off all Masks (we cant turn the GSYSTEM MASK, even if we try ....)
            TurnOffInputMaskCommand tof = new TurnOffInputMaskCommand(InputMask.GALL);
            CommandProcessor.getCommandProcessor().SendCommandAssyncronous(tof);

            ///Turn only the right mask
            ///Masks are Bit Field, You can turn more than one using InputMask.GALL | InputMask.G1 for example
            ///The TurnOnInputMaskCommand Just combine its actual mask with the mask provided, It does not TURN OFFthe active masks (this is the reason why i sent a turn off mask before)
            TurnOnInputMaskCommand tom = new TurnOnInputMaskCommand(Im[index] | InputMask.GNONE);
            CommandProcessor.getCommandProcessor().SendCommandAssyncronous(tom);

            isAllActive = false;
            isGroup1 = false;
            isGroup2 = false;
            isComboPressed = false;
            isChangeGroup = true;
        }

        public void Multiple(InputPlayableKeyBoard ipk)
        {
            isGroup1 = false;
            isGroup2 = false;
            isComboPressed = true;
        }

    }
}

The code for this demo can be found in our Introduction Demos package, you can download it here. (there are lots of others demos in this package, we will explain each of them in the next tutorials)

Any doubts, critics, suggestions, pls go to our forum or leave a comment here.

See you guys =P

Links

 

 

, , , , , ,

  1. #1 by Daron Pinnow on 24 de março de 2017 - 2:50 pm

    JT Foxx

  2. #2 by jobs db in hong kong hong kong career fair hong kong good jobs hong kong indeed jobs hong kong scmp jobs monster hong kong jobs 香港搵工 on 24 de março de 2017 - 2:51 pm

    Do you mind if I quote a couple of your posts as long as I provide credit and sources back to your webpage?
    My blog site is in the exact same niche as yours and my visitors would genuinely benefit from
    some of the information you provide here. Please let me know if this okay with you.
    Appreciate it!

  3. #3 by taruhan bola online terpercaya on 24 de março de 2017 - 3:32 pm

    Thank you for the auspicious writeup. It actually used
    to be a entertainment account it. Glance complex to far added agreeable from you!
    By the way, how can we communicate?

  4. #4 by hong kong employment hong kong job market on 24 de março de 2017 - 3:32 pm

    Excellent post. I’m dealing with many of these issues as well..

  5. #5 by geico.com on 24 de março de 2017 - 3:33 pm

    I appreciate regarding nice review that truthfully promote getting novel provisitions. The best feature to choose rates is online compare process which provides the most wanted offers on landlord insurance policies provided from top rated companies like American family in USA.

  6. #6 by luxury brands glasses on 24 de março de 2017 - 3:33 pm

    Hi to all, the contents present at this web site are truly awesome for people experience,
    well, keep up the nice work fellows.

  7. #7 by fuck on 24 de março de 2017 - 3:43 pm

    With havin so much written content do you ever run into any problems of plagorism or copyright
    infringement? My site has a lot of unique content I’ve either authored myself
    or outsourced but it looks like a lot of it is popping
    it up all over the internet without my authorization. Do you know any methods to help stop content
    from being stolen? I’d really appreciate it.

  8. #8 by http://www.tier1graphicsusa.com/western-qbe-car-insurance.html on 24 de março de 2017 - 3:55 pm

    Hello just thought i would tell you something.. This is twice now i’ve landed on your blog in the last 3 days looking for totally unrelated things. Spooky or what?

  9. #9 by 秘書 on 24 de março de 2017 - 3:57 pm

    Incredible points. Outstanding arguments. Keep up the good spirit.

  10. #10 by Batman Injustice 2 on 24 de março de 2017 - 4:07 pm

    Do you have a spam problem on this blog; I also am a blogger, and I was wanting to know your situation; we have developed some
    nice procedures and we are looking to exchange strategies with others,
    be sure to shoot me an e-mail if interested.

  11. #11 by www.adultfrinendfinder.com on 24 de março de 2017 - 4:10 pm

    Yes! Finally something about b n.

  12. #12 by http://www.sinnottsautosales.com/cycle-insurance-online.html on 24 de março de 2017 - 4:11 pm

    Yep, those botanists will go right on categorizing new plants long after the bullets stop flying. That may lead to the realization that there are two distinct types of plant life on Safehold once the heretical theory of evolution is proposed. Bleek!

  13. #13 by mobile legend hack on 24 de março de 2017 - 4:18 pm

    very nice page we have at this time how everybody’s first impressions at our page with regards to mobile legend hack

  14. #14 by 16193A on 24 de março de 2017 - 4:22 pm

    This design is wicked! You obviously know how to keep a reader
    amused. Between your wit and your videos, I was almost moved to start my own blog
    (well, almost…HaHa!) Wonderful job. I really loved what you had to say, and more than that, how
    you presented it. Too cool!

  15. #15 by nowy lek na prostate on 24 de março de 2017 - 4:22 pm

    Badanie stężenia antygenu PSA jest jak rzut monetą:
    pozwala ona na zdiagnozowanie jedynie 3,8% przypadków
    raka; oznacza to, że 96,2% nowotworów pozostaje niezdiagnozowane!

  16. #16 by pussy fuck on 24 de março de 2017 - 5:26 pm

    Hey I am so grateful I found your website, I really found you by mistake, while I was researching on Google for something
    else, Regardless I am here now and would just like to say kudos for a fantastic post and a all round exciting blog (I also love
    the theme/design), I don’t have time to read it all at the minute but I have book-marked it and also added in your RSS feeds, so when I have time I will be back to read a lot more, Please do keep up the excellent b.

  17. #17 by Masha driving Spiderman's car nearly hit Joker on 24 de março de 2017 - 5:27 pm

    This is my first time pay a visit at here and i am truly happy to
    read everthing at alone place.

  18. #18 by mylesaobo813692.blogocial.com on 24 de março de 2017 - 5:43 pm

    I went over this site and I think you have lots of excellent information, saved to faves.

  19. #19 by Fellsattel on 24 de março de 2017 - 5:53 pm

    Hey there! I realize this is sort of off-topic however
    I had to ask. Does building a well-established blog such as yours take a lot of work?

    I am completely new to writing a blog but I do
    write in my journal everyday. I’d like to start a blog so I will be able to share my experience and views online.
    Please let me know if you have any recommendations or tips for brand new aspiring bloggers.
    Appreciate it!

  20. #20 by Moupmdw on 24 de março de 2017 - 6:10 pm

    STAP論文がインチキなら、いくらハーバードが大金持ちだからと言って、そんな捨て金を使うでしょうか?しかしながら、負担はそれだけでは済みません。 大ヒットは「まったく予期していなかった」というミラー監督に電話で話を聞いた。 [url=http://forum.tsukaeru.net/viewtopic.php?p=31522#31522]日本ドラマ HERO 1-2 DVD-BOX[/url]
     プロに教わる事が出来るからまずはどのクラブも芯にしっかり当ててスイングのチェックをして貰うつもりだ。 一方、大韓航空も現地に整備員とタイヤメーカー関係者を派遣した。
    [url=http://z12.invisionfree.com/JimmyCoatesForum/index.php?showtopic=14384]韓国ドラマ ママ~最後の贈りもの~ DVD-BOX 価格[/url] 特に需要の高い外国語としては、トップは英語、次いで中国語となっています。 逆に上手な人には小細工が効かないみたいですが、私にとっては最適!土曜日の会社帰りに購入の意志を固めでショップ巡り。
    [url=http://blackhand.forumcity.com/viewtopic.php?p=3303#3303]韓国ドラマ 運命のように君を愛してる DVD-BOX[/url]
    相変わらず不調が続いているが,此処3日位は一応順調な日が続いたということで,Updateが上手くいけば正常に戻るかも知れないのでそれを期待しているのだと云う。 《PC復活への道》:2016/09/03(土)アマチュア無線交信LOGソフト「ターボハムログ」専用機として運用していたSONY VAIO PCG-C1MRXもついにハードディスク(以下HDD)がガラガラ音発生と共にクラッシュし、ついにシステムのWindows XPが起動しなくなった。 [url=http://z12.invisionfree.com/JimmyCoatesForum/index.php?showtopic=14384]韓国ドラマ ママ~最後の贈りもの~ DVD-BOX 価格[/url]
    写真はその道中、ちょこっと寄った来島海峡大橋の展望台。 レンズがプラッチックだと他のアルコール(メタノールやエタノール)ではもれなくクラックが入ってダメになる。
    [url=http://z12.invisionfree.com/JimmyCoatesForum/index.php?showtopic=14384]韓国ドラマ ママ~最後の贈りもの~ DVD-BOX激安[/url]  *図版のキャプションは編集部によるものです。 7.今後使用を考え 期限1日前にマイクロソフトHPから手動でアップグレード。
    [url=http://lea-aix.leforum.eu/t126012.htm#p139882]日本ドラマ ナポレオンの村 DVD-BOX[/url]

  21. #21 by loan car to friend insurance on 24 de março de 2017 - 6:10 pm

    I’m so glad I found my solution online.

  22. #22 by Diet Supplements on 24 de março de 2017 - 6:23 pm

    Pretty! This was an extremely wonderful post. Thanks for providing this info.

  23. #23 by pa insurance code on 24 de março de 2017 - 6:39 pm

    I like the valuable info you supply in your articles. I will bookmark your weblog and check once more right here regularly. I’m fairly certain I’ll be informed a lot of new stuff right right here! Good luck for the following!

  24. #24 by Nurses on 24 de março de 2017 - 7:34 pm

    It is not my first time to pay a visit this site, i am browsing this web page
    dailly and get pleasant data from here all
    the time.

  25. #25 by http://www.sinnottsautosales.com/discovery-car-insurance.html on 24 de março de 2017 - 7:36 pm

    Now we know who the sensible one is here. Great post!

  26. #26 by nature sounds on 24 de março de 2017 - 7:52 pm

    When someone writes an paragraph he/she retains the idea of a user in his/her brain that how a user can understand it.
    Thus that’s why this article is perfect. Thanks!

  27. #27 by location on 24 de março de 2017 - 7:53 pm

    Keep all the articles coming. I love reading your posts.
    All the best.

  28. #28 by http://www.evolutionhairdressers.com/second-chance-car-insurance.html on 24 de março de 2017 - 8:01 pm

    I don’t disagree that Germany had it coming, not one bit. I completely agree that they (or most of them anyway), supported Hitler right up till things turned bad. . .but the last act was still awful. Necessary, but horrible just the same. As an aside, nobody, IMHO, fought with more cause than those Soviet soldiers with the watches. That particular photograph, for me, is one of the more memorable WWII photos, along with the Marine flag-raising picture at Iwo Jima (I believe I read that the Soviet photographer was aware of that photo, and was looking for a similar effect).

  29. #29 by example on 24 de março de 2017 - 8:05 pm

    Thank you for this post, I’m a big fan of this web site would want
    to be updated.

  30. #30 by as example on 24 de março de 2017 - 8:09 pm

    Howdy, You have performed an admirable job. I’ll surely
    digg it and for my part suggest to my friends.
    I’m confident they’ll be benefiting from this site.

  31. #31 by Afiliado ultimate funciona on 24 de março de 2017 - 8:11 pm

    Eu não até sabe o caminho parei até
    aqui , mas Eu assumi isto publicar costumava ser
    grande. Eu não reconhecer quem você está no entanto certamente és
    vai um famoso blogger no evento você não são já.

    Um brinde!

  32. #32 by http://www.warburtongallery.com/insurance-companies-hiring.html on 24 de março de 2017 - 8:19 pm

    olá Paula. sou deficiente visual e infelizmente não consegui ler seu artigo na revista tam on line. Li um papo sobre deficiência e digo que vc está de parabéns pelas colocações.

  33. #33 by harga gazebo on 24 de março de 2017 - 8:30 pm

    Sweet blog! I found it while browsing on Yahoo News.
    Do you have any tips on how to get listed in Yahoo News?
    I’ve been trying for a while but I never seem to get
    there! Thank you

  34. #34 by Relief on 24 de março de 2017 - 8:38 pm

    Hi, i think that i saw you visited my website
    so i came to go back the desire?.I am attempting to to find issues to enhance my
    site!I suppose its ok to use a few of your ideas!!

  35. #35 by best on 24 de março de 2017 - 8:39 pm

    Good article. I’m experiencing a few of these issues as well..

  36. #36 by yeezy boost 350 v2 white red on 24 de março de 2017 - 8:40 pm

  37. #38 by find business contact details in guntur on 24 de março de 2017 - 8:45 pm

    Wow! Finally I got a web site from where I be capable of truly take helpful facts regarding
    my study and knowledge.

  38. #39 by http://news.ingdaily.com/ingdaily/752.asp on 24 de março de 2017 - 8:47 pm

    I have this particular gift of the mother of Xmas due she are per jewelry freak. That the one thing she cannot wear much regarding are, bracelets. I bought her our appeal bracelet furthermore whenever she exposed things yesterday she absolutley enjoyed they! This time the problem is actually, this girl obtaining it on and off by just herself. Haha… general very good goods, things shipped additionally came severely early as well as the mom was experiencing things. Thank people.

  39. #40 by http://news.ordersoho.com/ordersoho/738.asp on 24 de março de 2017 - 8:48 pm

    it comes down within a pretty container appears great however it is a bit little consistent for the my personal mothers wrist however it looks very good only really want it is longer

  40. #41 by http://news.cartierreplica.top/cartierreplicatop/58.asp on 24 de março de 2017 - 8:48 pm

    it comes down in a beautiful box styles awesome still it is slightly mini additionally for the our moms wrist but it appearance great just really want things ended up being much longer

  41. #42 by http://news.vancleefreplica.top/vancleefreplicatop/80.asp on 24 de março de 2017 - 8:48 pm

    it comes down within a stunning container appearance awesome however their slightly little still towards my personal mothers wrist however it appears ideal just desire information technology ended up being longer

  42. #43 by college essay writing service on 24 de março de 2017 - 8:48 pm

    Great site you’ve got here.. It’s hard to find good quality
    writing like yours nowadays. I honestly appreciate people like you!

    Take care!!

  43. #44 by business opportunities in china on 24 de março de 2017 - 8:49 pm

    Hey there! I just wanted to ask if you ever have
    any issues with hackers? My last blog (wordpress) was hacked and I ended up losing months of hard work
    due to no backup. Do you have any methods to protect against hackers?

1 1.838 1.839 1.840
(não será publicado)