SRL Archive - Discussions & Debates

Muilti-threading with simba.


rj

2013-05-19 22:48:29

I think this would be a great feature, so let me go into some detail of why I think it would be cool if it were added.



What is muilti-Threading?

- Pretty much, (somebody please explain this better) in noob terms, it's a script inside your script running while your script is running. So that means progress reports could be in real time, calling randoms could be in real time (checking for them as your doing something else)



SRL is a learning community. There are many things I have learned here scripting wise aside from Runescape botting, just to name a few:

- cases
- good program structure
- avoiding memory leaks
- Procedure and function parameters (made my basic java skills a little better)


Back to my main point:

From: Officer Barbrady
SRL is a learning community


That being said, I think that Muilti-threading support should be added. It would be a great thing to be added to expand my knowledge and many others around on this forum. Of course, as we all know it is NOT absolutely needed for Runescape botting, infact it is not needed at all. It would be a mere extra thing will no major significance scripting wise. But me, and many other newbie scripters, muilti-threading support with simba would greatly expand our knowlege on programming in general!


Let's move on to some Pros and Cons if this "muilti-threading" was added.



Pros:

- As I have already said, and this is the main reason, a GREAT learning experience. This is pretty much most of the reason I would love this. If you disagree with me note that this is the main reason I want this added.
- Could be extremely useful for checking for randoms in OSRS
- Could offer slightly more support for debugging things such as SPS walking or any other walking (current position while walking a path, this can be done now but would be a pain because SPS_walkpath goes through an array of tpoints and you would have to call the procedure inbetween different sets of TPoints and it wouldn't be the same..)
- Real time progress reports.
- Have double-form progress report - an example of this is the iDungeon from RSbuddy had a progress report at the bottom, you could click buttons on the progress report and update the script accordingly
-
From: Ashaman88
Yes I would use it


Cons:

- Inexperience. If muilti-threading is not used properly, it WILL cause memory leaks MUCH worse then some mere "un freed DTMs". This is a major con when considering adding muilti-threading to simba. It's not like you can highlight the procedure you want to muilti-thread and right click "muilti-thread".
- Actually adding it. I don't develop Simba. I have no idea if this would be easy or hard to do. I don't know if it would be worth it with the amount of work that would be required.




Post what you think below. I personally think it would be a good learning experience.

King

2013-05-19 22:50:27

From: Officer Barbrady
I think the difference is huge though, it would be much more complicated then just freeing DTM's and bitmaps on terminate.


Well if people want to use it they will learn it properly. I understand where you are coming from with memory leaks being larger, but it wont be any different than a non functional script is now. PB has a huge memory leak issue, just close the client is all. People will only be able to learn how to do this through trial and error anyways. I think it is just a more extreme version of "Script did not compile". I dont think it will be any different than using TPA's, people who know how will, people who dont wont :P


My reply until it was moved :P

tealc

2013-05-19 22:59:17

From what I understand, which isn't much, multithreading can be done but it wouldn't be thread safe http://en.wikipedia.org/wiki/Thread_safety

Did you try what Brandon suggested in your last multithreading thread http://villavu.com/forum/showthread.php?t=96205

Ashaman88

2013-05-19 23:22:53

Yes I would use it

senrath

2013-05-19 23:25:39

I'll be honest. If all you want multithreading in Simba for is to learn, you should probably try picking up a language other than Pascal and learning it there. I haven't delved into the source code of Simba at all, but adding in multithreading is probably not going to be the easiest task in the world and would more than likely add in a whole slew of new and irritating bugs to be dealt with.

Kevin

2013-05-19 23:30:54

I thoroughly enjoy my multi-threading experience and would love to add it to my scripts. It could improve so many different aspects. While pretty much everything could be done without multi-threading, threads would make so many things far easier.

I suppose I haven't looked into what language Simba is written in, but I've worked on creating multi-threaded frameworks in a few different languages, so I will offer any help I can.

Brandon

2013-05-19 23:43:05

From: senrath
I'll be honest. If all you want multithreading in Simba for is to learn, you should probably try picking up a language other than Pascal and learning it there. I haven't delved into the source code of Simba at all, but adding in multithreading is probably not going to be the easiest task in the world and would more than likely add in a whole slew of new and irritating bugs to be dealt with.


This is true but the only thing I see standing in the way of multi-threading is the interpretter.. Like actually getting the thread to run a function within Simba.

The only problem I see with Multi-Threading is synchronism. This is kinda one of those features always suggested like SimbaToExe.. Except that Multi-Threading would increase script power by a TON!

If functions within Simba's editor actually have a memory address, then this would be a singe to add.. No sweat a all with a plugin or editing Simba.. The reason I say this is because if we can do "AddOnTerminate(FunctionAddress)" or "CallProc(FunctionAddress)" somehow, then what's stopping "CreateThread(FunctionAddress)"?

senrath

2013-05-19 23:49:43

From: Brandon
This is true but the only thing I see standing in the way of multi-threading is the interpretter.. Like actually getting the thread to run a function within Simba.

The only problem I see with Multi-Threading is synchronism. This is kinda one of those features always suggested like SimbaToExe.. Except that Multi-Threading would increase script power by a TON!

If functions within Simba's editor actually have a memory address, then this would be a singe to add.. No sweat a all with a plugin or editing Simba.. The reason I say this is because if we can do "AddOnTerminate(FunctionAddress)" or "CallProc(FunctionAddress)" somehow, then what's stopping "CreateThread(FunctionAddress)"?


Personally I'd like to see us move away from PascalScript and onto Lape before we worry about multi-threading.

rj

2013-05-20 00:00:01

From: senrath
Personally I'd like to see us move away from PascalScript and onto Lape before we worry about multi-threading.


Lape needs to be pushed more then, so far i dont see a lot of people talking it up or any tutorials for that matter.

Kevin

2013-05-20 00:15:22

From: Officer Barbrady
Lape needs to be pushed more then, so far i dont see a lot of people talking it up or any tutorials for that matter.


It's almost like I constantly here some huge advocation for Lape all the time… From some source, I just can't put my finger on… *cough* @Ollybest *cough* It's almost like I feel there are a ridiculous amount of advantages towards moving towards Lape. And that this would be a great time for someone, I don't know who (Olly :p), to list these reasons and bring a greater public vision and appeal towards it…

Flight

2013-05-20 00:15:38

From: senrath
Personally I'd like to see us move away from PascalScript and onto Lape before we worry about multi-threading.


From what I've heard so far I really agree with Senrath on this. And @ the OP, of course this would be a wonderful tool for writing scripts and anti-randoms, any scripter would agree on that. It would surely give us a boost. Who this thread should really be targeting is Wizzup?, Dgby714 and of course nielsie95: the Simba / Lape dev. team.

Olly

2013-05-20 00:18:48

no offence, but it won't happen there's way more needed stuff than multithreading.

fyi - this thread isnt new, its been talked about for years but no one wants/needs to do it http://villavu.com/forum/showthread.php?t=66682

CynicRus

2013-05-20 01:15:29

In scripts do not need multi-threading. For everything else we have natify(@you_proc) by Dgby714.

Flight

2013-05-20 05:17:12

From: CynicRus
In scripts do not need multi-threading. For everything else we have natify(@you_proc) by Dgby714.


Oh on the contrary my friend, it would be very useful for scripters to be able to run multiple events simultaneously. Also, what is 'natify'? I've never heard of such a thing. When was that added to Simba?

masterBB

2013-05-20 05:20:58

From: senrath
Personally I'd like to see us move away from PascalScript and onto Lape before we worry about multi-threading.


No, we can add it to lape without changing ps.

CynicRus

2013-05-20 05:50:20

From: Flight
Oh on the contrary my friend, it would be very useful for scripters to be able to run multiple events simultaneously. Also, what is 'natify'? I've never heard of such a thing. When was that added to Simba?


https://github.com/MerlijnWajer/Simba/pull/185/files - that is what you needed for you task:)

Flight

2013-05-20 06:29:02

From: CynicRus
https://github.com/MerlijnWajer/Simba/pull/185/files - that is what you needed for you task:)


Nice. I looked in "http://nala.villavu.com/downloads/master/" but the latest Simba (Simba.i386-win32.exe only) I could find was from April 30 and apparently doesn't include 'Natify'.

On a far, far side note, every Simba > 993 gives an access violation error when trying to use SPS; I wonder why? My permissions are changed as administrative ect…

senrath

2013-05-20 08:36:16

From: masterBB
No, we can add it to lape without changing ps.


So we can add it to Lape without delaying its full release and adoption any further?

CynicRus

2013-05-20 08:59:32

Maybe you can get version with natify here? http://l0.lt/one_line_per_build

Turpinator

2013-05-20 10:42:58

From: Officer Barbrady
Lol, I would just use it for real time proggies if it were to be added


All Ive gathered is that you just want multithreading for super fast proggies.

Kevin

2013-05-20 10:57:03

From: Turpinator
All Ive gathered is that you just want multithreading for super fast proggies.


This can be done with tight loops where you call your proggress update more often instead of simply waiting for every action in your script to occur iteratively through waits. I'm *pretty-sure* Superuser does this in his irony script. Just look it over and you should be able to figure out how to do it.

Flight

2013-05-20 11:24:08

From: CynicRus
Maybe you can get version with natify here? http://l0.lt/one_line_per_build


Yes the one I have is from 2013-Apr-30 11:13:46. That's okay though, I'll wait until it's public. I'm more concerned on why anything above 993 gives access violation errors when it comes to SPS…

Oh my, trying to compile this (below) crashes the newest Simba build:

{$DEFINE LAPE}
{$I SRL/SRL.Simba}

begin
SetupSRL;
end.

Error:

Program exception!
Stacktrace:

Exception class: EAccessViolation
Message: Access violation
$00000000
$0040BFA2
Simba Version: 1000

I don't know if this is helpful for you, CynicRus, but here's Simba's Debug box as I try to compile the above:


I hope the information helps.

Coh3n

2013-05-20 12:57:55

If you want multi-threading just to expand your programming knowledge, I highly recommend taking up another language. Pascal is used virtually nowhere.

People can argue multi-threading would be useful in scripting all they want, but I'll always disagree. If you write your script properly, it's completely unnecessary. A good progress report should take a few ms to print, and if you check for randoms in the right places, it accomplishes the same.

Putting that aside, though, multi-threading would be very, very low priority. There are a lot of things (both in Simba and Lape) that need to be done before multi-threading is considered (at least in my opinion, and I'm sure the Lape developers would agree).

All in all, it's possible, but not useful enough to make it worth it, so don't expect something to happen anytime soon (if at all).

Flight

2013-05-20 13:59:21

From: Coh3n
If you want multi-threading just to expand your programming knowledge, I highly recommend taking up another language. Pascal is used virtually nowhere.


If that were the case then I'm sure this question would appear on a programming community, but since it's asked here, in the community that focuses on Simba it's safe to assume he's wanting multi-threading in Simba, not another program. Now I didn't read all of the OP but I can only assume that Officer Barbrady is only interested in multi-threading if it's included with Simba, if not then it's not worth it to completely switch to a different program.

From: Coh3n

People can argue multi-threading would be useful in scripting all they want, but I'll always disagree. If you write your script properly, it's completely unnecessary. A good progress report should take a few ms to print, and if you check for randoms in the right places, it accomplishes the same.


Yes indeed we can come very close to accomplishing everything we would expect from a multi-thread Simba, in our scripts, but it would be much better to do this correct rather than trying to mimic multi-threading in a script. It would be a tool to make certain tasks easier & faster. For specific uses I'd have to sit down and think as off the top of my head only a few come to mind.

From: Coh3n

Putting that aside, though, multi-threading would be very, very low priority. There are a lot of things (both in Simba and Lape) that need to be done before multi-threading is considered (at least in my opinion, and I'm sure the Lape developers would agree).

All in all, it's possible, but not useful enough to make it worth it, so don't expect something to happen anytime soon (if at all).


I would agree as this is no where near high priority, not many people are jumping at the suggestions. You'll see most of us just agree on "It'd be nice if we have it, but no it's not the end of the world if we don't". And yeah that was brought up of continuing work on Lape long before we ever got to this stage.


So I mostly agree with you Coh3n, I don't see it as high priority and from my understanding there's much more important projects to be dumping time & effort into before we look at a task like multi-threading. But again, being a script, I for one would enjoy such a feature, but you won't catch me holding my breath.

CynicRus

2013-05-20 14:19:59

I don't know why you get this error, because my Simba is compiled from the same sources with my own hands and I don't have any problems with it. Also, before I committed an lcl code I had tested it deeply and all tests passed without any errors or problems, and natify worked fine.

Cheers,
Cynic.

Dgby714

2013-05-20 15:33:43

From: Officer Barbrady
@Zyt3x - Lape developer, seemed as pumped in 2011 about this

Not a Lape Developer…

From: Officer Barbrady
Ollybest - Sorry you don't get 2 mentions :) - lape developer

Not a Lape Developer…. Just an idiot.

From: Officer Barbrady
@Dgby714 - another lape addict

I am a Simba Developer, not a Lape Developer.

I have looked into adding Threading methods, it is possible, but becomes very unstable as Lape and Simba are not threadsafe.

From: Flight
Also, what is 'natify'? When was that added to Simba?

Natify returns a native memory location you can call from say a plugin to a script method.
It was added recently and will be in dev versions of Simba located at http://l0.lt/

Brandon

2013-05-20 15:59:26

From: Dgby714

Natify returns a native memory location you can call from say a plugin to a script method.
It was added recently and will be in dev versions of Simba located at http://l0.lt/


What do you mean by this? Does it return the address of a script function so that plugins can call it or the address of plugin functions so scripts can call it because the latter is pretty useless since plugins can export functions already..

Dgby714

2013-05-20 16:06:03

From: Brandon
What do you mean by this? Does it return the address of a script function so that plugins can call it?


It returns the address of a sudo-method that calls a lape interpreter to call that method.

Coh3n

2013-05-20 22:26:02

From: Flight
If that were the case then I'm sure this question would appear on a programming community, but since it's asked here, in the community that focuses on Simba it's safe to assume he's wanting multi-threading in Simba, not another program. Now I didn't read all of the OP but I can only assume that Officer Barbrady is only interested in multi-threading if it's included with Simba, if not then it's not worth it to completely switch to a different program.
He said he wanted it to expand his programming knowledge. If you want to do that, it would be better to learn new languages. If all he wants it for is Simba then yes, obviously it would be better for him to have it in Simba. :p

From: Flight

So I mostly agree with you Coh3n, I don't see it as high priority and from my understanding there's much more important projects to be dumping time & effort into before we look at a task like multi-threading. But again, being a script, I for one would enjoy such a feature, but you won't catch me holding my breath.
I agree. :) If it was there, I'd use it. It's just not needed.

Flight

2013-05-20 22:38:07

From: Coh3n
He said he wanted it to expand his programming knowledge. If you want to do that, it would be better to learn new languages. If all he wants it for is Simba then yes, obviously it would be better for him to have it in Simba. :p

I agree. :) If it was there, I'd use it. It's just not needed.


I see, I clearly did not read the full OP, heh, silly of me. Yes, if this thread revolves around multi-threading for a learning purpose then there's better alternatives as opposed to Simba.

grats

2013-05-20 22:59:25

Voted, but in all honesty it hits both yes's
I think it's pretty silly to learn programming in this day and age, and not learn at least some simple multi threading techniques, it is very important in progression for the future.. not only for simba, but for every and all programs.

techniques as in.. you can't searching for a monster to click, while antiban goes off; it would mess up a lot. Different ways of thinking for scripting, because currently stuff only happens in a line

Flight

2013-05-21 04:02:44

From: CynicRus
I don't know why you get this error, because my Simba is compiled from the same sources with my own hands and I don't have any problems with it. Also, before I committed an lcl code I had tested it deeply and all tests passed without any errors or problems, and natify worked fine.

Cheers,
Cynic.


Well I downloaded the absolute newest (#448 from April 30) from that site, this time downloading the installer and completely re-installing Simba. Still have have the same problem, Simba crashing each and every time I hit compile when the interpreter is set to Lape. Even the "Program new; begin end." crashes Simba at exactly the same place, every time. Also, this absolute latest version of Simba does not recognize "Natify".

From: Dgby714

Natify returns a native memory location you can call from say a plugin to a script method.
It was added recently and will be in dev versions of Simba located at http://l0.lt/


Is there a build > #448 ? That's the latest I can find and it crashes 100% of the time with Lape, it also does not recognize Natify.

Daniel

2013-05-21 05:19:53

No. And in the context of Simba's needs, it's stupid and I will always say no.

denart5

2013-05-21 09:16:28

It would be good for learning, I've no idea what is or how it would work lol

CynicRus

2013-05-21 10:04:44

From: Flight
Well I downloaded the absolute newest (#448 from April 30) from that site, this time downloading the installer and completely re-installing Simba. Still have have the same problem, Simba crashing each and every time I hit compile when the interpreter is set to Lape. Even the "Program new; begin end." crashes Simba at exactly the same place, every time. Also, this absolute latest version of Simba does not recognize "Natify".



Is there a build > #448 ? That's the latest I can find and it crashes 100% of the time with Lape, it also does not recognize Natify.


http://rghost.ru/46156739 - I've compile it for you from sources, this version of simba works fine.

Flight

2013-05-21 10:10:10

From: CynicRus
http://rghost.ru/46156739 - I've compile it for you from sources, this version of simba works fine.


Wonderful, I shall indeed try this out tonight. Thank you CynicRus. :)

Oh my… From Chrome: "MySimba.zip appears malicious."

CynicRus

2013-05-21 11:37:49

He's wrong, but if you are worried about this message, just decompress this exe with upx. I've tested it with Microsoft forefront before uploading.

Brandon

2013-05-21 12:14:54

From: Dgby714
It returns the address of a sudo-method that calls a lape interpreter to call that method.



Well in that case I got multi-threading working.. Partially I guess.. Using CynicRus' build with Natify and based off what you just said, the following is certainly threaded and it works.. Only problem is that if the Thread is not stopped, Simba will crash and this is because std::thread requires that it is either "Joined" or "Detached" before the thread goes out of scope. Of course it would be easy to place this stopping in a destructor but why not let the user do that right? I think my stopping is broken anyway.. Probably need to use std::atomic<bool> for thread stopping. It can be modified to take infinite arguments but of course natify does all the work so all we needed was an address..

Anyway, the following prints sleeping and hello world at the same time.. The threaded one ('hello world') prints in Simba's console and the non-threaded function (writeln('Sleeping..')) prints in Simba's debug box. Stupid example of a threadpool but its an example that is proof that multi-threading can be done without messing up anything else in Simba.

Explanation:

A boolean is required to stop the infinite loop. If you attempt to stop the script first, the thread will go out of scope and you will crash your Simba. Thus you must set the boolean to true to stop the loop then the thread will automatically die. This simba test example is perfect and will not crash. It will simply multi-thread SAFELY. Safety is obviously in the hands of the user then since they are required to stop the thread because it would be stupid of me to babysit and add that functionality to the destructor.


Simba Test:

{$loadlib SmartThreading}

var
Stop: Boolean;

Procedure Run;
begin
while(Not Stop) do
begin
writeln('Hello Thread World!');
Sleep(100);
end;
end;

var
I, ThreadID: Integer;
begin
Stop := False;
ThreadID := ThreadFunction(Natify(@Run));
For I := 0 To 5 Do
Begin
writeln('Sleeping...');
Sleep(1000);
End;

Stop := True;
StopThreadFunction(ThreadID);
end.

Threading.hpp:

#ifndef THREADING_HPP_INCLUDED
#define THREADING_HPP_INCLUDED

#include <iostream>
#include <fstream>
#include <thread>
#include <atomic>
#include <system_error>
#include <map>

class Threading
{
private:
std::map<std::uint32_t, std::thread> ThreadPool;

public:
Threading() {};

template<class Function, class... Args>
std::uint32_t StartThread(Function&& FunctionToPass, Args&&... args);

std::uint32_t StartThread(std::function<void()>& FunctionToPass);

void StopThread(std::uint32_t ThreadID);
};

template<class Function, class... Args>
std::uint32_t Threading::StartThread(Function&& FunctionToPass, Args&&... args)
{
ThreadPool.insert(std::pair<std::uint32_t, std::thread>(ThreadPool.size() + 1, std::thread(FunctionToPass, args...)));
return ThreadPool.size();
}

#endif // THREADING_HPP_INCLUDED


Threading.cpp


#include "Threading.hpp"

std::uint32_t Threading::StartThread(std::function<void()> &FunctionToPass)
{
ThreadPool.insert(std::pair<std::uint32_t, std::thread>(ThreadPool.size() + 1, std::thread(FunctionToPass)));
return ThreadPool.size();
}

void Threading::StopThread(std::uint32_t ThreadID)
{
try
{
std::map<std::uint32_t, std::thread>::iterator it = this->ThreadPool.find(ThreadID);

if (it != this->ThreadPool.end())
{
it->second.detach();
ThreadPool.erase(it);
}
}
catch (...){}
}

Main.cpp

#include <windows.h>
#include "Threading.hpp"

#define NumberOfExports 2
HINSTANCE hInstance = nullptr;
Threading ThreadPool;

static char* Exports[] = {
(char*)"ThreadFunction", (char*)"Function ThreadFunction(FunctionToPass: Pointer): Integer",
(char*)"StopThreadFunction", (char*)"Procedure StopThreadFunction(ThreadID: Integer);"
};

extern "C" std::uint32_t ThreadFunction(void* Pointer)
{
std::function<void()> FunctionToPass((void(*)())Pointer);
return ThreadPool.StartThread(FunctionToPass);
}

extern "C" void StopThreadFunction(std::uint32_t ThreadID)
{
ThreadPool.StopThread(ThreadID);
}

extern "C" int GetFunctionInfo(int Index, void* &Address, char* &Definition)
{
if (Index < NumberOfExports)
{
Address = (void*)GetProcAddress(hInstance, Exports[Index * 2]);
strcpy(Definition, Exports[Index * 2 + 1]);
return Index;
}

return -1;
}

extern "C" int GetFunctionCount()
{
return NumberOfExports;
}

extern "C" int GetPluginABIVersion()
{
return 2;
}

extern "C" bool __stdcall DllMain(HINSTANCE hinst, int fdwReason, void* lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hInstance = hinst;
break;

case DLL_PROCESS_DETACH:
// detach from process
break;

case DLL_THREAD_ATTACH:
// attach to thread
break;

case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}

Threading.def:

EXPORTS
GetFunctionCount
GetFunctionInfo
GetPluginABIVersion

ThreadFunction
StopThreadFunction


Done in codeblocks..

CynicRus

2013-05-21 12:42:48

I have a thread pool implementation for LAzarus, but I don't sure about it working in Linux. Also, thread in Lasarus its a class, and all threads its just inheritance for TThread class. But with natify it hink we can implement this task in Simba. But I'm not sure if this is necessary.

Dgby714

2013-05-21 15:02:48

From: Brandon
Well in that case I got multi-threading working.. Partially I guess.. Using CynicRus' build with Natify and based off what you just said, the following is certainly threaded and it works.. Only problem is that if the Thread is not stopped, Simba will crash and this is because std::thread requires that it is either "Joined" or "Detached" before the thread goes out of scope. Of course it would be easy to place this stopping in a destructor but why not let the user do that right? I think my stopping is broken anyway.. Probably need to use std::atomic<bool> for thread stopping. It can be modified to take infinite arguments but of course natify does all the work so all we needed was an address..

Anyway, the following prints sleeping and hello world at the same time.. The threaded one ('hello world') prints in Simba's console and the non-threaded function (writeln('Sleeping..')) prints in Simba's debug box. Stupid example of a threadpool but its an example that is proof that multi-threading can be done without messing up anything else in Simba.

Explanation:

A boolean is required to stop the infinite loop. If you attempt to stop the script first, the thread will go out of scope and you will crash your Simba. Thus you must set the boolean to true to stop the loop then the thread will automatically die. This simba test example is perfect and will not crash. It will simply multi-thread SAFELY. Safety is obviously in the hands of the user then since they are required to stop the thread because it would be stupid of me to babysit and add that functionality to the destructor.


Simba Test:

{$loadlib SmartThreading}

var
Stop: Boolean;

Procedure Run;
begin
while(Not Stop) do
begin
writeln('Hello Thread World!');
Sleep(100);
end;
end;

var
I, ThreadID: Integer;
begin
Stop := False;
ThreadID := ThreadFunction(Natify(@Run));
For I := 0 To 5 Do
Begin
writeln('Sleeping...');
Sleep(1000);
End;

Stop := True;
StopThreadFunction(ThreadID);
end.

Threading.hpp:

#ifndef THREADING_HPP_INCLUDED
#define THREADING_HPP_INCLUDED

#include <iostream>
#include <fstream>
#include <thread>
#include <atomic>
#include <system_error>
#include <map>

class Threading
{
private:
std::map<std::uint32_t, std::thread> ThreadPool;

public:
Threading() {};

template<class Function, class... Args>
std::uint32_t StartThread(Function&& FunctionToPass, Args&&... args);

std::uint32_t StartThread(std::function<void()>& FunctionToPass);

void StopThread(std::uint32_t ThreadID);
};

template<class Function, class... Args>
std::uint32_t Threading::StartThread(Function&& FunctionToPass, Args&&... args)
{
ThreadPool.insert(std::pair<std::uint32_t, std::thread>(ThreadPool.size() + 1, std::thread(FunctionToPass, args...)));
return ThreadPool.size();
}

#endif // THREADING_HPP_INCLUDED


Threading.cpp


#include "Threading.hpp"

std::uint32_t Threading::StartThread(std::function<void()> &FunctionToPass)
{
ThreadPool.insert(std::pair<std::uint32_t, std::thread>(ThreadPool.size() + 1, std::thread(FunctionToPass)));
return ThreadPool.size();
}

void Threading::StopThread(std::uint32_t ThreadID)
{
try
{
std::map<std::uint32_t, std::thread>::iterator it = this->ThreadPool.find(ThreadID);

if (it != this->ThreadPool.end())
{
it->second.detach();
ThreadPool.erase(it);
}
}
catch (...){}
}

Main.cpp

#include <windows.h>
#include "Threading.hpp"

#define NumberOfExports 2
HINSTANCE hInstance = nullptr;
Threading ThreadPool;

static char* Exports[] = {
(char*)"ThreadFunction", (char*)"Function ThreadFunction(FunctionToPass: Pointer): Integer",
(char*)"StopThreadFunction", (char*)"Procedure StopThreadFunction(ThreadID: Integer);"
};

extern "C" std::uint32_t ThreadFunction(void* Pointer)
{
std::function<void()> FunctionToPass((void(*)())Pointer);
return ThreadPool.StartThread(FunctionToPass);
}

extern "C" void StopThreadFunction(std::uint32_t ThreadID)
{
ThreadPool.StopThread(ThreadID);
}

extern "C" int GetFunctionInfo(int Index, void* &Address, char* &Definition)
{
if (Index < NumberOfExports)
{
Address = (void*)GetProcAddress(hInstance, Exports[Index * 2]);
strcpy(Definition, Exports[Index * 2 + 1]);
return Index;
}

return -1;
}

extern "C" int GetFunctionCount()
{
return NumberOfExports;
}

extern "C" int GetPluginABIVersion()
{
return 2;
}

extern "C" bool __stdcall DllMain(HINSTANCE hinst, int fdwReason, void* lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hInstance = hinst;
break;

case DLL_PROCESS_DETACH:
// detach from process
break;

case DLL_THREAD_ATTACH:
// attach to thread
break;

case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}

Threading.def:

EXPORTS
GetFunctionCount
GetFunctionInfo
GetPluginABIVersion

ThreadFunction
StopThreadFunction


Done in codeblocks..


Don't get mad when your Lape starts Access Violating for no reason.

Also, CynicRus, something you are doing is causing Wizzup's builds to access violate when compiling scripts…..

I told you something was wrong with your class exports. I think you may be using a different fpc/las?

CynicRus

2013-05-21 16:30:49

From: Dgby714
Don't get mad when your Lape starts Access Violating for no reason.

Also, CynicRus, something you are doing is causing Wizzup's builds to access violate when compiling scripts…..

I told you something was wrong with your class exports. I think you may be using a different fpc/las?


I think, Wizzup's build don't have libffi.dll in Simba.exe place….

Dgby714

2013-05-21 17:21:59

From: CynicRus
I think, Wizzup's build don't have libffi.dll in Simba.exe place….


Why does your class exports need libffi? Are you using Natify internally?

Brandon

2013-05-21 22:14:21

From: Dgby714
Don't get mad when your Lape starts Access Violating for no reason.


And why would it? As long as the threads are destroyed properly and don't all try modifying things at the same time and don't destroy resource created by the script, there should be no reason for an access violation. All the functions exist in the same address space regardless of whether they're threaded or not.. If I wrote a plugin to just call a function without a thread it would have the same exact potential for errors as one that runs the function in a thread. The Pascal-Script data-types are atomic OR volatile as far as I can tell because changing the boolean to false in the main thread caused the second thread to stop looping infinitely. If it wasn't atomic, the the second thread wouldn't see the change at all.. Pretty safe as far as I can tell. I also tried two thread running the same function. Works just fine.. Multiple threads running different functions also work..

So if you're saying that the plugin above will cause Lape to throw access violation errors, then it would throw them normally regardless of whether the plugin threaded the function or just called it in the same main thread.. Unless you have some sort of an example I'm unaware of that may cause abnormal termination.. I don't see a reason why Lape will just throw.



From: Daniel
No. And in the context of Simba's needs, it's stupid and I will always say no.


Do you just say no for the sake of saying no or do you have a fear of change or just dislike extra functionality because other than "Simba's NEEDS" which isn't defined in that sentence, I don't see a reason for that "no". It isn't a need but a lot of people would "Want" it and it'd simply add extra functionality that could have been there a while back. I'd understand if Simba developers just came out and said "No just because" or "No we fear users will use it wrong" or "No its too much work".. but to just say "No" or "No it's stupid" isn't a valid reason.

Flight

2013-05-21 23:17:58

From: Brandon

Do you just say no for the sake of saying no or do you have a fear of change or just dislike extra functionality because other than "Simba's NEEDS" which isn't defined in that sentence, I don't see a reason for that "no". It isn't a need but a lot of people would "Want" it and it'd simply add extra functionality that could have been there a while back. I'd understand if Simba developers just came out and said "No just because" or "No we fear users will use it wrong" or "No its too much work".. but to just say "No" or "No it's stupid" isn't a valid reason.


Well said, an excellent point.

The same could be said about 90% of what we use in Simba & scripts; it's not required but it's a tool that we can utilize. Do we need the SRL include to make scripts for Runescape? No. Do we need a DTM editor, SPS or even SMART? Not at all. But because we have the ability to make these tools and they're much preferred, why be so quick to deny the practicality of them?

CynicRus

2013-05-21 23:43:28

From: Dgby714
Why does your class exports need libffi? Are you using Natify internally?


libffi uses only your natify, and this just an idea. Because I had use same compiler as you, and I have no problems, then the problem is in something else. I had the same problem because of the libffi doesn't exists in the simba.exe folder. But today I once again its code base.

Dgby714

2013-05-22 11:47:27

From: Brandon
And why would it? As long as the threads are destroyed properly and don't all try modifying things at the same time and don't destroy resource created by the script, there should be no reason for an access violation. All the functions exist in the same address space regardless of whether they're threaded or not.. If I wrote a plugin to just call a function without a thread it would have the same exact potential for errors as one that runs the function in a thread. The Pascal-Script data-types are atomic OR volatile as far as I can tell because changing the boolean to false in the main thread caused the second thread to stop looping infinitely. If it wasn't atomic, the the second thread wouldn't see the change at all.. Pretty safe as far as I can tell. I also tried two thread running the same function. Works just fine.. Multiple threads running different functions also work..

So if you're saying that the plugin above will cause Lape to throw access violation errors, then it would throw them normally regardless of whether the plugin threaded the function or just called it in the same main thread.. Unless you have some sort of an example I'm unaware of that may cause abnormal termination.. I don't see a reason why Lape will just throw.


Nether Lape nor Simba are threadsafe, your "other" threads cannot use most of MML. Unless you actually use the Client variable.

There is a chance Lape will access violate, I don't quite know how it works internally, but I'm pretty sure it wasn't made to have one "interpreter" running two separate sections of the code at the same time.



From: Brandon
Do you just say no for the sake of saying no or do you have a fear of change or just dislike extra functionality because other than "Simba's NEEDS" which isn't defined in that sentence, I don't see a reason for that "no". It isn't a need but a lot of people would "Want" it and it'd simply add extra functionality that could have been there a while back. I'd understand if Simba developers just came out and said "No just because" or "No we fear users will use it wrong" or "No its too much work".. but to just say "No" or "No it's stupid" isn't a valid reason.


We have said all of those reasons…

Dgby714

2013-05-22 11:49:52

From: CynicRus
libffi uses only your natify, and this just an idea. Because I had use same compiler as you, and I have no problems, then the problem is in something else. I had the same problem because of the libffi doesn't exists in the simba.exe folder. But today I once again its code base.


Natify being there won't segfault unless you actually call it while registering methods.

It seems to segfault when registering TCustomLabel.

I'll just add a check in Natify that raises a exception if libffi is missing.

The exception has nothing to do with Natify…. You're trying to add children of TGraphicControl and you never define TGraphicControl.

Brandon

2013-05-22 13:09:21

From: Dgby714
Nether Lape nor Simba are threadsafe, your "other" threads cannot use most of MML. Unless you actually use the Client variable.

There is a chance Lape will access violate, I don't quite know how it works internally, but I'm pretty sure it wasn't made to have one "interpreter" running two separate sections of the code at the same time.

We have said all of those reasons…



Hmm wasn't made for it but it works for all except that.. It does indeed throw in a second Thread for LibMML stuff.. Just another Simba limitation :l. Lape doesn't recognize TClient in Simba so that's a no-no.

Dgby714

2013-05-22 13:29:30

From: Brandon
Hmm wasn't made for it but it works for all except that.. It does indeed throw in a second Thread for LibMML stuff.. Just another Simba limitation :l. Lape doesn't recognize TClient in Simba so that's a no-no.


It does on newer Simbas… It's just a variable called Client.

CynicRus

2013-05-22 14:15:41

From: Dgby714
Natify being there won't segfault unless you actually call it while registering methods.

It seems to segfault when registering TCustomLabel.

I'll just add a check in Natify that raises a exception if libffi is missing.

The exception has nothing to do with Natify…. You're trying to add children of TGraphicControl and you never define TGraphicControl.

Weird. Because we have a different sources, and when I compile it manually I have a fine result, as you can see above. Tomorrow I will take a look to it again.

Dgby714

2013-05-22 14:33:16

From: CynicRus
Weird. Because we have a different sources, and when I compile it manually I have a fine result, as you can see above. Tomorrow I will take a look to it again.


This means you're ether forgetting to send a file with pull requests, or you have a modified file you're not adding to commits.

CynicRus

2013-05-22 15:12:38

From: Dgby714
This means you're ether forgetting to send a file with pull requests, or you have a modified file you're not adding to commits.


Hm…Maybe. Well, I will take a look to it tomorrow:)

slushpuppy

2013-05-22 22:19:00

This will open simba to a larger dimension of botting. The limitations of Simba inhibits programmers from making macro scripts that can be widely adopted for other games/applications. Even sharing a memory block, with PascalSscript, from a plugin is already a goddamn task by itself.

With multithreading, we will not be limited to static screen scraping. Instead we will be able to record animations(at periods of many seconds), then compare them with other recorded animations without ever blocking the main program flow. This application can also be used for sound detection.

You would be a massive philistine at this day and age not to realize the potential of Simba, if it did away with its many inhibitions

Daniel

2013-05-23 04:53:16

From: Brandon
Do you just say no for the sake of saying no or do you have a fear of change or just dislike extra functionality because other than "Simba's NEEDS" which isn't defined in that sentence, I don't see a reason for that "no". It isn't a need but a lot of people would "Want" it and it'd simply add extra functionality that could have been there a while back. I'd understand if Simba developers just came out and said "No just because" or "No we fear users will use it wrong" or "No its too much work".. but to just say "No" or "No it's stupid" isn't a valid reason.


Coming from you, that is very surprising to hear. You should know full well that it is a stupid idea to implement multi-threading within Simba's scripting engines just to satisfy the ardent curiosity of people who don't know how it works and not knowing how un-useful it will be. What do they want to use it for? Simultaneous progress reports, and [e.g.] checking monster positions whilst in a fight! The latter which can be accomplished by simply running those very checks in that wait-loop that performs anti-ban every thirty seconds.

Think for a moment about how you would implement threading in a Simba script. You would separate your "monster position checks" from the main script thread, and run that thread continuously. Then, if it does find the monster has moved, it synchronises with the main script thread, which has to be running in a continuous loop to check the state of the other thread. Pretty much accomplishes the same in a more complex manner than not multi-threading that task, doesn't it?

Multi-threading for macroing in a game isn't at all useful.

From: Flight
Well said, an excellent point.

The same could be said about 90% of what we use in Simba & scripts; it's not required but it's a tool that we can utilize. Do we need the SRL include to make scripts for Runescape? No. Do we need a DTM editor, SPS or even SMART? Not at all. But because we have the ability to make these tools and they're much preferred, why be so quick to deny the practicality of them?


What has that got to do with anything? Multi-threading isn't all the bells and whistles you hope for it to be.

Brandon

2013-05-23 05:30:46

From: Daniel
Coming from you, that is very surprising to hear. You should know full well that it is a stupid idea to implement multi-threading within Simba's scripting engines just to satisfy the ardent curiosity of people who don't know how it works and not knowing how un-useful it will be.

Multi-threading for macroing in a game isn't at all useful.

What has that got to do with anything? Multi-threading isn't all the bells and whistles you hope for it to be.



And why would Multi-threading be "Un-useful". Your example is specifically for runescape but even so, how would it be not useful for macroing.. Multi-threading can be used for non-blocking purposes: One such example is to have a Form and its callback run in another thread without blocking the Main. The advantage is that if you click something in the form, it automatically updates the variable's contents in the main thread and that you don't have to close the form like you currently do due to it being modal and that blocks. Scheduled timers/tasks is also an advantage.

Live progress reports would also be useful. Constantly searching while walking.. Have a thread do a lengthy task (perhaps sort a large array) and when its completed, it can notify the main that its done and the data is ready to be used.. No need for synchronization because we don't care when its finished or we wouldn't use a thread. Just that it lets us know when its done so we can use it. That right there introduces events into Simba as well as Locking.

Linear programming isn't all that you make it out to be. I can accomplish many tasks and many features with multi-threading as without.

You shouldn't be so quick to place a limitation on all users. Just because some don't have uses or don't know how to use it, doesn't mean others won't find it useful or know how to use it. As a developer myself, I don't just throw out random limitations to users of my programs. I give them options and if need be, I limit those options.

I already know this isn't going to happen though.

Dgby714

2013-05-23 06:38:28

From: Brandon
And why would Multi-threading be "Un-useful". Your example is specifically for runescape but even so, how would it be not useful for macroing.. Multi-threading can be used for non-blocking purposes: One such example is to have a Form and its callback run in another thread without blocking the Main. The advantage is that if you click something in the form, it automatically updates the variable's contents in the main thread and that you don't have to close the form like you currently do due to it being modal and that blocks. Scheduled timers/tasks is also an advantage.

Live progress reports would also be useful. Constantly searching while walking.. Have a thread do a lengthy task (perhaps sort a large array) and when its completed, it can notify the main that its done and the data is ready to be used.. No need for synchronization because we don't care when its finished or we wouldn't use a thread. Just that it lets us know when its done so we can use it. That right there introduces events into Simba as well as Locking.

Linear programming isn't all that you make it out to be. I can accomplish many tasks and many features with multi-threading as without.

You shouldn't be so quick to place a limitation on all users. Just because some don't have uses or don't know how to use it, doesn't mean others won't find it useful or know how to use it. As a developer myself, I don't just throw out random limitations to users of my programs. I give them options and if need be, I limit those options.

I already know this isn't going to happen though.


Forms should only be in the main thread… and they can be unblocking anyways.

Daniel

2013-05-23 06:51:02

From: Brandon
One such example is to have a Form and its callback run in another thread without blocking the Main. The advantage is that if you click something in the form, it automatically updates the variable's contents in the main thread and that you don't have to close the form like you currently do due to it being modal and that blocks. Scheduled timers/tasks is also an advantage.

Forms are always run on a thread independent (the main thread) of the thread executing the script. Windows forms are not inherently thread safe. If you don't want it to block, call Show.

From: Brandon

Live progress reports would also be useful.


How so? Apart from updating the amount of ores mined, or logs banked.


From: Brandon

Constantly searching while walking..


You can already do that without threads (see the last sentence of the first paragraph of my initial response to you).

From: Brandon
Have a thread do a lengthy task (perhaps sort a large array) and when its completed, it can notify the main that its done and the data is ready to be used..

But for what [realistic] purpose would we use that for? If it is for something other than macroing (Simba's primary purpose and reason for being, despite how much we love to deny it), then use another language, or put it into a DLL (if you need Simba, and speed).

From: Brandon

Linear programming isn't all that you make it out to be. I can accomplish many tasks and many features with multi-threading as without.

You shouldn't be so quick to place a limitation on all users. Just because some don't have uses or don't know how to use it, doesn't mean others won't find it useful or know how to use it.

I know it isn't.

And I admit that I am being a bit pessimistic about its usability, but that is from within the context of the current system of botting that we use. I just cannot see very many pros versus the cons of implementing it.

Brandon

2013-05-23 07:25:07

From: Dgby714
Forms should only be in the main thread… and they can be unblocking anyways.


Why? What rule is there in programming or scripting that says Windows/Forms should only be spawned in the main thread? If its the safety rule then see the below code which is just as safe as a non-threaded version. And no it cannot be unblocked in Simba because when that happens, the windows disappears immediately.


See here: http://villavu.com/forum/showthread.php?t=65657&p=825500#post825500

From: Daniel
Forms are always run on a thread independent (the main thread) of the thread executing the script. Windows forms are not inherently thread safe. If you don't want it to block, call Show.



They cannot.. If you call Show on a Form in Simba, as soon as you click another window, bye bye form. ShowModal is what is always called. I've tried this already with my GUI's on Smart plugin. The only way for the form to stay alive is to call the native SetParent(HWND) function and give the form a parent that is visible.


Second.. Forms aren't run in a separate thread. If it was, it wouldn't block the main thread unless its implemented badly.

Since when are Windows Forms not thread safe? You can "SAFELY" run the following code as much as you want AND paint the window as well.. With the Lambda's Capture abilities, you can also pass it variables/functions to create dynamically shaped windows all while being threaded..

I can spawn tons of these and none will block main or throw and none are dangerous or unsafe. I've even attached Async sockets to these to make chat clients.. So what was that about them not being natively thread-safe? Yeah I guess I didn't think about the walking one.. The others are still done linearly by calling things in a loop every other line or w/e.. Still not the same.


In Java:

new Thread(new Runnable() {
JFrame F = new JFrame("Some Window Title");
F.setVisible(true);
}).start();

In C++:

void CreateThreadedWindow()
{
std::thread T([&]{
WNDPROC WindowProcedure = [](HWND window, UINT msg, WPARAM wp, LPARAM lp) -> LRESULT __stdcall
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(window, msg, wp, lp);
}
return 0;
};

WNDCLASSEX WndClass =
{
sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
0, 0, GetModuleHandle(nullptr), LoadIcon(nullptr, IDI_APPLICATION),
LoadCursor(nullptr, IDC_ARROW), HBRUSH(COLOR_WINDOW+1),
nullptr, "WindowClass", LoadIcon (nullptr, IDI_APPLICATION)
};

if (RegisterClassEx(&WndClass))
{
HWND WindowHandle = CreateWindowEx(0, "WindowClass", "SomeWindowTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
if (WindowHandle)
{
MSG msg = {nullptr};
ShowWindow(WindowHandle, SW_SHOWDEFAULT);
while(GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}

});

T.detach();
}

Can also write it in ASM with a call to CreateThread.. so no nativity problem there :l


Mhmm.. I realized something.. There will never be a realistic purpose for anything on SRL will there..

But like I said, this is a debate thread and I know this isn't going to be implemented "just because". Safety is not an issue. And certain Windows "nativity" is not an issue. The issue is Simba or the developers. If you don't want it, you don't have to add it but don't make excuses about why its bad because there is nothing bad about an extra feature. Especially one like threading.

Daniel

2013-05-23 08:05:34

From: Brandon
They cannot.. If you call Show on a Form in Simba, as soon as you click another window, bye bye form. ShowModal is what is always called.

That doesn't happen?

var
frmMain: TForm;
Params: TVariantArray;

procedure InitialiseForm;
begin
frmMain := TForm.Create(nil);
frmMain.Show;
end;

begin
ThreadSafeCall('InitialiseForm', Params);
repeat
Writeln('Random line...');
Sleep(500);
Until(IsKeyDown(VK_F3));
frmMain.Close;
frmMain.Free;
end.

From: Brandon

Second.. Forms aren't run in a separate thread. If it was, it wouldn't block the main thread unless its implemented badly.


I never said they were? I said they were run in the main thread (via ThreadSafeCall). And ShowModal, by design, causes it to block.

From: Brandon

Since when are Windows Forms not thread safe? You can "SAFELY" run the following code as much as you want AND paint the window as well..

I said they weren't inherently thread safe. For example, accessing the form and modifying its controls from multiple threads can pretty much cause it to die if it isn't done in a thread safe manner.

From: Brandon
The issue is Simba or the developers. If you don't want it, you don't have to add it but don't make excuses about why its bad because there is nothing bad about an extra feature. Especially one like threading.


You're right. There is nothing bad about adding an extra feature. However, implementing a feature such as threading takes time, and the cons outweigh the pros (as outlined in previous posts, unless you've just been ignoring them…) Besides, I am not a Simba developer. I am just a regular ol' denizen who disagrees that implementing multi-threading will be the best thing ever and required for this community to move forward.

Dgby714

2013-05-23 11:23:17

From: Brandon
Why? What rule is there in programming or scripting that says Windows/Forms should only be spawned in the main thread? If its the safety rule then see the below code which is just as safe as a non-threaded version. And no it cannot be unblocked in Simba because when that happens, the windows disappears immediately


Unblocking works fine, you're just doing it wrong.

Creating forms and any component for that matter if unsafe in secondary threads. That is why we have ThreadSafeCall which calls the method in the main thread. (This only applies to LCL)

Here's an paragraph from http://wiki.freepascal.org/Multithreaded_Application_Tutorial.

Lazarus Widgetset Interfaces

The win32, the gtk and the carbon interfaces support multi-threading. This means, TThread, critical sections and Synchronize work. But they are not thread safe. This means only one thread at a time can access the LCL. And since the main thread should never wait for another thread, it means only the main thread is allowed to access the LCL, which means anything that has to do with TControl, Application and LCL widget handles. There are some thread safe functions in the LCL. For example most of the functions in the FileUtil unit are thread safe.

Brandon

2013-05-23 14:43:35

@Daniel; I like that example. Duly noted. However, this is what you said:


Forms are always run on a thread independent of the thread executing the script.


Now think about it. If the thread running the script is the main thread. What makes you think "Forms" are run on a separate thread independent of the Main if Dbgy just said that its ran in the main? Contradicting each other.



From: Dgby714
Creating forms and any component for that matter if unsafe in secondary threads.


Absolutely the worst fallacy I have ever heard about threading.. Sorry. My example still stands. If you wanted something cross platform you could have just asked and I would be more than happy to post code using wXWidgets which is as cross platform as it gets OR I can ifdef all my windows/linux code.. Pascal also contains a preprocessor ifdef and that can be used for cross-platform code if that's what you're worried about. Simba barely even works in x64 mode, I wouldn't worry about cross-platform so much when it still has to be run in Wine..


Creating components or forms in secondary threads are completely thread safe as long as you don't try and change the same component from multiple threads at the same time causing a LOCK or a Hang. Secondly, its pretty hard to get Windows and Linux to LOCK up a component because threads aren't truly parallel. There's only one CallBack function for processing messages in the Queue. If you actually get it to Lock up then you did it on purpose. There's also always a shared amount of processor power each thread gets. One thread always runs at some split-second interval after another. Never at the "exact" same time.



Also your Windows examples don't really help if you don't realize Simba is developed with many OS' in mind, tho PascalScript doesn't support some, Lape will.

But they are not thread safe. This means only one thread at a time can access the LCL. And since the main thread should never wait for another thread, it means only the main thread is allowed to access the LCL.



My windows example DOES help because it can easily be done on Linux the exact same way. How can you also ignore the Java example? Infact, JFrames must be created in the EDT (Event Dispatch Thread) and sometimes used with InvokeAndWait so main has to wait anyway!.. Are you going to say that Creating Components or Forms are not safe in Java then? And its cross-platform/cross-compiler. I do threading on both Linux & Windows for game programming and it works just fine.

std::threads are cross-platform and use the native threading API's on that specific platform. On windows it uses wrappers around WinAPI's CreateThread function and on Linux it uses PThread under the hood. TThreads on windows most likely use WinAPI's CreateThread.


Don't worry, I know what threading is. I don't need a tutorial or you bolding it with size 5 for me. I've read that the last time this argument came up. Always some excuse. I'll rephrase the bold for you: "It can't be done in Pascal because wiki says so or language is too primitive or we just don't know how".


And since the main thread should never wait for another thread.


LOL.. Have you tried mutexes, sephamores or kernel locks yet? I'm fairly certain the "Main" thread has to "wait" for the lock to be freed in order to use the object being locked. Again, you shouldn't place your own rules on others. Main thread waits on a lot of things. Like I said, threading notifications/events.. You can use them to notify main. No one said that main would wait on a threaded form to process its events.


However, Daniel posted an example that does work and is non-modal. So there isn't much left that is worth the work of adding threading to Simba.

Dgby714

2013-05-23 15:20:47

From: Brandon
@Daniel; I like that example. Duly noted. However, this is what you said:



Now think about it. If the thread running the script is the main thread. What makes you think "Forms" are run on a separate thread independent of the Main if Dbgy just said that its ran in the main? Contradicting each other.





Absolutely the worst fallacy I have ever heard about threading.. Sorry. My example still stands. If you wanted something cross platform you could have just asked and I would be more than happy to post code using wXWidgets which is as cross platform as it gets OR I can ifdef all my windows/linux code.. Pascal also contains a preprocessor ifdef and that can be used for cross-platform code if that's what you're worried about. Simba barely even works in x64 mode, I wouldn't worry about cross-platform so much when it still has to be run in Wine..


Creating components or forms in secondary threads are completely thread safe as long as you don't try and change the same component from multiple threads at the same time causing a LOCK or a Hang. Secondly, its pretty hard to get Windows and Linux to LOCK up a component because threads aren't truly parallel. There's only one CallBack function for processing messages in the Queue. If you actually get it to Lock up then you did it on purpose. There's also always a shared amount of processor power each thread gets. One thread always runs at some split-second interval after another. Never at the "exact" same time.





My windows example DOES help because it can easily be done on Linux the exact same way. How can you also ignore the Java example? Infact, JFrames must be created in the EDT (Event Dispatch Thread) and sometimes used with InvokeAndWait so main has to wait anyway!.. Are you going to say that Creating Components or Forms are not safe in Java then? And its cross-platform/cross-compiler. I do threading on both Linux & Windows for game programming and it works just fine.

std::threads are cross-platform and use the native threading API's on that specific platform. On windows it uses wrappers around WinAPI's CreateThread function and on Linux it uses PThread under the hood. TThreads on windows most likely use WinAPI's CreateThread.


Don't worry, I know what threading is. I don't need a tutorial or you bolding it with size 5 for me. I've read that the last time this argument came up. Always some excuse. I'll rephrase the bold for you: "It can't be done in Pascal because wiki says so or language is too primitive or we just don't know how".



LOL.. Have you tried mutexes, sephamores or kernel locks yet? I'm fairly certain the "Main" thread has to "wait" for the lock to be freed in order to use the object being locked. Again, you shouldn't place your own rules on others. Main thread waits on a lot of things. Like I said, threading notifications/events.. You can use them to notify main. No one said that main would wait on a threaded form to process its events.


However, Daniel posted an example that does work and is non-modal. So there isn't much left that is worth the work of adding threading to Simba.


First, Scripts are not ran on the main thread. The ThreadSafeCall method is basically a TThread.Sync for scripts.

Second, Simba (in terms of Lape which this thread is about) works on any OS FreePascal and Lazarus can compile for.

Third, Your examples doesn't apply as we have to follow the rules that Lazarus and FreePascal impose. (Not Simba)
If you're using a plugin in another language to create windows and other threads, it doesn't really apply to this thread, as this threads about adding Threading to Lape. (I think talking about Threading in a thread is getting confusing…)

Dgby714

2013-05-23 15:27:08

Ok this has turned into two different arguments…

We need to move the forms argument to another thread.

The reasons why we have not added Threading to Lape has been said in this thread.

If anyone wants to add Threading thru a plugin, go ahead, tho you should read FreePascal's page on threading.

There are problems with threading in plugins (especially with other languages), that are explained in the page.

rj

2013-05-23 15:46:17

So what I am getting from this, is people want to wait until Lape IF they want to do anything at all, but Lape isn't expected to be done until a long time now right?

Oh and no double posting Dgby714 :) :p

Dgby714

2013-05-23 16:23:27

From: Officer Barbrady
So what I am getting from this, is people want to wait until Lape IF they want to do anything at all, but Lape isn't expected to be done until a long time now right?

Oh and no double posting Dgby714 :) :p


Well, Olly got the threading stuff from me, which I was doing in Lape.

Lape is done enough… It's really not missing much.

rj

2013-05-23 16:26:51

From: Dgby714
Well, Olly got the threading stuff from me, which I was doing in Lape.

Lape is done enough… It's really not missing much.


Then what's being delayed? :s it seems that nobody is paying attention to it, it needs to it's section instead of being just a sub category

Kevin

2013-05-23 16:28:51

From: Dgby714
Well, Olly got the threading stuff from me, which I was doing in Lape.

Lape is done enough… It's really not missing much.


If we developers would start scripting in LAPE and leaving PS in the dust (thus forcing everyone to follow suit to use our scripts), would that help the final official LAPE takeover come sooner?

Dgby714

2013-05-23 16:51:41

From: Kevin
If we developers would start scripting in LAPE and leaving PS in the dust (thus forcing everyone to follow suit to use our scripts), would that help the final official LAPE takeover come sooner?


The Lape takeover will happen ether way.

Simba 1.0 will still have PS as the primary interpreter.
I'm pretty sure Simba 1.1 will switch to Lape as primary and PS as secondary.
Then shortly after that we will drop PS completely.

One concern is SRL-OSR, it's more for PS than Lape atm.

Olly

2013-05-23 16:55:10

From: Officer Barbrady
Then what's being delayed? :s it seems that nobody is paying attention to it, it needs to it's section instead of being just a sub category


From: Kevin
If we developers would start scripting in LAPE and leaving PS in the dust (thus forcing everyone to follow suit to use our scripts), would that help the final official LAPE takeover come sooner?


No, imo its waiting on SRL6 mainly, regardless everyone thinks lape is some massive change like going from ps to java, but im pretty damn sure 99% of current scripts would compile if the include compiles.

Kevin

2013-05-23 16:57:16

From: Dgby714
The Lape takeover will happen ether way.

Simba 1.0 will still have PS as the primary interpreter.
I'm pretty sure Simba 1.1 will switch to Lape as primary and PS as secondary.
Then shortly after that we will drop PS completely.

One concern is SRL-OSR, it's more for PS than Lape atm.


I understand Lape is coming either way, I was just curious about getting lape as official earlier than if noone tried switching (which is answered by your simba release comment). Along the direction of your new mention however; how often is simba officially updated to new versions like that?

Daniel

2013-05-23 22:12:38

From: Brandon
@Daniel; I like that example. Duly noted. However, this is what you said:

No no, you're misquoting. I mentioned that the independent thread was the main thread. Scripts are not run on the main thread, but on a separate thread for each script (that's why you can run two scripts at the same time, and the Simba form still remains responsive to input).

From: Kevin
If we developers would start scripting in LAPE and leaving PS in the dust (thus forcing everyone to follow suit to use our scripts), would that help the final official LAPE takeover come sooner?



Yes. It's just the lack of adoption as to why Lape isn't being used (yet). AFAIK, SRL6 is Lape-only, which will [hopefully] cease scripters using PascalScript.

rj

2013-06-06 19:05:57

Bump.

Lets reopen this discussion

double codes

2013-06-17 18:35:52

Sorry for grave-digging.

Yes, i am myself a kinda decent VB.NET programmer and Multi-Threading was one of the best functions i added to my application.
I remember i used Timers every time i wanted to "Loop" something without freezing the window i still use timers if i am lazy.

Though i only need around 3-5 lines of code to add Multi-Threading to my applications, though i think it will be very differently in Simba.

Memory leaks can be fixed, Do IT!

bg5

2013-12-05 11:58:54

Maybe someone may find it silly, but I have my idea of pseudo-multithreading:

• Simba can run two or more scripts operating on the same target simultaneously in different tabs.
• You can manually pause/resume script pressing a button.

All we need is to export pausing/resuming to 2 functions, like:


function PauseScript(TabNumber: byte) : boolean;
function ResumeScript(TabNumber: byte) : boolean;




For example, what we want to do is:

Go from Point A to B using SPS, if meet goblin on the way then kill and loot him.

This simple instruction wouldn't be possible without multithreading or modificating SPS by nesting FindGoblin() function inside it ( propably by replacing Wait(time) gaps with something like WaitAndCheckForGoblin(time) ,which would mess up SPS and make it useless for any other application).


But if we have pause/resume functions it would be very simple:

When in tab 1 we run SPS and stuff, in tab 2 we search for goblin and run something like this:


procedure SearchForGoblin();
begin
.
.
.
if (FindGoblin() = TRUE ) then
begin
PauseScript(tab1); // SPS will stop now
KillGoblin();
LootGoblin();
ResumeScript(tab1); // SPS will continue walking to destination
end;
.
.
.
end;


Also memory between tabs can be shared inside file or if someone wants to use RAM for it - inside dll. This way main script (tab1) can control what's happening in tab 2, e.x.:


program tab1;
procedure MainLoop();
begin
SharedVar := 1;
GoFromAtoB();
SharedVar := 2;
GoFromBtoC();
SharedVar := 3;
GoFromCtoA();
end;




program tab2;
procedure MainLoop();
begin
while(SharedVar = 1) do SearchForGoblin();
while(SharedVar = 2) do SearchForScorpion();
while(SharedVar = 3) do SearchForMod();

end;


rj

2013-12-12 15:36:13

From: bg5
Maybe someone may find it silly, but I have my idea of pseudo-multithreading:

• Simba can run two or more scripts operating on the same target simultaneously in different tabs.
• You can manually pause/resume script pressing a button.

All we need is to export pausing/resuming to 2 functions, like:


function PauseScript(TabNumber: byte) : boolean;
function ResumeScript(TabNumber: byte) : boolean;




For example, what we want to do is:

Go from Point A to B using SPS, if meet goblin on the way then kill and loot him.

This simple instruction wouldn't be possible without multithreading or modificating SPS by nesting FindGoblin() function inside it ( propably by replacing Wait(time) gaps with something like WaitAndCheckForGoblin(time) ,which would mess up SPS and make it useless for any other application).


But if we have pause/resume functions it would be very simple:

When in tab 1 we run SPS and stuff, in tab 2 we search for goblin and run something like this:


procedure SearchForGoblin();
begin
.
.
.
if (FindGoblin() = TRUE ) then
begin
PauseScript(tab1); // SPS will stop now
KillGoblin();
LootGoblin();
ResumeScript(tab1); // SPS will continue walking to destination
end;
.
.
.
end;


Also memory between tabs can be shared inside file or if someone wants to use RAM for it - inside dll. This way main script (tab1) can control what's happening in tab 2, e.x.:


program tab1;
procedure MainLoop();
begin
SharedVar := 1;
GoFromAtoB();
SharedVar := 2;
GoFromBtoC();
SharedVar := 3;
GoFromCtoA();
end;




program tab2;
procedure MainLoop();
begin
while(SharedVar = 1) do SearchForGoblin();
while(SharedVar = 2) do SearchForScorpion();
while(SharedVar = 3) do SearchForMod();

end;



Meh I wouldn't want to go through that much trouble to have bootleg multithreading

bg5

2013-12-13 06:43:26

From: Officer Barbrady
Meh I wouldn't want to go through that much trouble to have bootleg multithreading


Trouble. You wanted multithreading, didn't you? It can't be much easier then that.

Kevin

2013-12-13 12:59:30

From: bg5
Trouble. You wanted multithreading, didn't you? It can't be much easier then that.


He wants someone else to go through the trouble of it so all he has to do is
Thread.New(() => { //whatever the thread will do});

Brandon

2013-12-13 15:04:47

From: Kevin
He wants someone else to go through the trouble of it so all he has to do is
Thread.New(() => { //whatever the thread will do});


Which was already done here: http://villavu.com/forum/showthread.php?t=103201&p=1240654#post1240654

Problem is that you can't use any of Simba's LibMML stuff as pointed out by dgby. Things like bitmap functions and finder functions for example won't work.

MAYBE sockets might work with it so you can have async sockets.. Don't know how it'd be useful if nothing in Simba can be threaded.

rj

2013-12-13 15:16:55

From: Kevin
He wants someone else to go through the trouble of it so all he has to do is
Thread.New(() => { //whatever the thread will do});


Nvm read the previous pages of the thread and i feel dumb for suggestion it in the first place


/close

Gu3st...

2013-12-13 16:39:40

No this is actually not a bad idea for pseudo-multithreading. I'd love this. We could start by making one (optional) tab for SRL-6 Smart Debugging. So if you want to, you can do {$DEFINE PSEUDOMULTITHREAD} before including SRL-6 and then if you open a new tab with the script we add to SRL-6/utilities/ or whatever then we can control all drawing on SMART from there: Include SRL Stats into this idea and we'd be able to do real-time debugging on multiple SMARTs.

Simba doesn't really *require* multi-threading, but it is of course the next step to go if we want Simba to evolve even more, and we don't exactly need the full hard-on multitasking which we know from other IDEs, but this pseudo-multithreading is *good enough* for Simba, imho.

From: Daniel
Coming from you, that is very surprising to hear. You should know full well that it is a stupid idea to implement multi-threading within Simba's scripting engines just to satisfy the ardent curiosity of people who don't know how it works and not knowing how un-useful it will be. What do they want to use it for? Simultaneous progress reports, and [e.g.] checking monster positions whilst in a fight! The latter which can be accomplished by simply running those very checks in that wait-loop that performs anti-ban every thirty seconds.

Think for a moment about how you would implement threading in a Simba script. You would separate your "monster position checks" from the main script thread, and run that thread continuously. Then, if it does find the monster has moved, it synchronises with the main script thread, which has to be running in a continuous loop to check the state of the other thread. Pretty much accomplishes the same in a more complex manner than not multi-threading that task, doesn't it?

Multi-threading for macroing in a game isn't at all useful.
I beg to differ.
One thread can be the master, while the others are slaves. The master thread will syncronize everything into one action meaning we can very easily develop an artificial intelligence include. One slave can be searching for monsters, and just telling the master what is found and where it is found if any is found, then the other slaves are also sending information to the master; the master thread can then have 5 or more actions it could perform and must choose for itself which one of them is the one with the highest priority.

Imagine a include that can search for animals while also searching for objects while also checking if the character is attacked while also checking if a JaGeX mod approaches simultaneously while also performing an action like clicking an ore or a tree.

Do all that simultaneously instead of one-by-one.

How is that not at all useful?

bg5

2013-12-15 04:46:59

From: Kevin
He wants someone else to go through the trouble of it so all he has to do is
Thread.New(() => { //whatever the thread will do});


Even if everything is perfectly worked out from Simba side, user still need to do what I've put in example above. I mean control additional thread somehow and synchronise it (on the level of script logic).


I think my solution is even quite easy to handle:

* different threads in different tabs
* extremely safe - no conflicts between threads, also Simba runs/destroys threads for you
* just 4 intuitive functions - very easy to understand
* also it's very simple to implement - just uses functions which are currently only assigned to menu buttons

Just replace

Thread.New();

with

TabRun(2);

and to stop thread
TabStop(2);

to interrupt

TabPause(2);
...
TabResume(2);

Of course it's only "pseudo" ,so it has some limits and lack of few features (like uhm ehm… critical sections) and it's not real in general, but I just give the simplest possible solution.

Olly

2013-12-16 10:27:32

@Brandon Do you mind sending a built version of http://villavu.com/forum/showthread.php?t=103201&page=2&p=1240654#post1240654 ? I have no c++ compiler and im guessing you do, although don't worry if your busy/dont have needed stuff to build.

I know you can't use mml stuff, but just want to mess around. :)

Brandon

2013-12-16 14:18:57

From: Olly
@Brandon Do you mind sending a built version of http://villavu.com/forum/showthread.php?t=103201&page=2&p=1240654#post1240654 ? I have no c++ compiler and im guessing you do, although don't worry if your busy/dont have needed stuff to build.

I know you can't use mml stuff, but just want to mess around. :)



Source + Binary: [ATTACH=CONFIG]22565[/ATTACH]


Example Usage:


{$loadlib Threading.dll}

var
SomeResource: Integer;
ThreadID, ThreadID2: Integer;
Stop: Boolean;

Procedure Func;
Begin
C_GlobalLock;
While(Not Stop) Do
Begin
SomeResource := 10;
writeln('Resource modified by Thread 1');
Sleep(500);
End;
C_GlobalUnlock;
End;

Procedure Func2;
Begin
C_GlobalLock;
While(Not Stop) Do
Begin
SomeResource := 11;
writeln('Resource modified by Thread 2');
Sleep(500);
End;
C_GlobalUnlock;
End;

Procedure StopThreads;
Begin
Stop := True;
C_JoinThread(ThreadID);
C_JoinThread(ThreadID2);
End;

begin
Stop := False;
ThreadID := C_CreateThread(Natify(@Func));
ThreadID2 := C_CreateThread(Natify(@Func2));
Sleep(2000);
AddOnTerminate('StopThreads');
end.


The above example demonstrates Synchronisation/Locking and Creating Threads as well as Terminating threads cleanly.

Exported functions:

Function C_CreateThread(FunctionToPass: Pointer): Integer;
Procedure C_DetachThread(ThreadID: Integer);
Procedure C_JoinThread(ThreadID: Integer);
Procedure C_ClearThreads(Join: boolean);
Function C_ThreadHardwareConcurrency: Integer;
Function C_NativeThreadID(ThreadID: Integer): Int64;

Function C_CreateLock: Integer;",
Procedure C_RemoveLock(LockID: Integer);",
Procedure C_Lock(LockID: Integer);",
Function C_TryLock(LockID: Integer): Boolean;",
Procedure C_Unlock(LockID: Integer);",
Procedure C_GlobalLock;",
Function C_GlobalTryLock: Boolean;
Procedure C_GlobalUnlock;
Procedure C_ClearLocks;

Can probably export more if needed. These are all portable and come from the C++11 standard.

I was actually going to write an Image plugin so you can thread images, draw on Smart/browser/anything via Process ID, etc..
That would make this threading plugin useful I guess..

Just remember that this will never work with LibMML or whatever it was Dgby said a while ago.

Kevin

2013-12-16 15:12:53

Why can't we use Multithreading with LibMML around @Dgby714?

  • Targetting specific windows and getting the window information such as their bitmaps and dimensions.
  • Controlling the mouse and keyboard.
  • Finding colours, bitmaps and dtms.
  • Text recognition (OCR)
  • Accessing files and sockets in an unified manner

Window targetting and the like should be able to be done on a process level and main-thread retaining control for the mouse and keyboard. Although reading from the targetted window should be available across threads fine? Files and sockets also can be done asynchronously just fine (is that just a LibMML limitation)?

Olly

2013-12-16 15:32:41

From: Brandon

…


heh, Well i guess it kinda is possible to multi thread drawing on smart.

I dont feel like figuring out the format of Simba bitmaps atm but here it is.
{$DEFINE SMART}
{$i srl-6/srl.simba}
{$loadlib Threading.dll}

var
SomeResource: Integer;
ThreadID: Integer;
Stop: Boolean;
data: PRGB32;
imgptr, w, h, i, t: integer;

procedure foo();
begin
imgptr := smartDebugArray(__smartCurrentTarget);
data := PRGB32(imgPtr);
end;

Procedure Func;
var
r: integer;
Begin
C_GlobalLock;

While (Not Stop) Do
Begin
r := random(high(integer));

for i := 120000 downto 0 do
data[i]^ := [r, r, r, r];

wait(500);
End;

C_GlobalUnlock;
End;

Procedure StopThreads;
Begin
Stop := True;
C_JoinThread(ThreadID);
End;

begin
smartEnableDrawing := true;
setupSRL();

foo();

Stop := False;
ThreadID := C_CreateThread(Natify(@Func));

t := (getSystemTime() + 5000);

while (t > getSystemTime()) do
writeln('AMG IM NOT DOING ANYTHING AND ITS DRAWING!!');


AddOnTerminate('StopThreads');
end.

Watch your smart screen flash while the rest of your script runs!

Accessing the raw data pointer via smart is just plane weird tho, I don't even know what to say…

{$DEFINE SMART}
{$i srl-6/srl.simba}

var
rawData: PRGB32;
i: integer;
begin
setupSRL();

rawData := PRGB32(smartDebugArray(__smartCurrentTarget));
writeln(@rawData);

for i := 0 to 10000 do
rawData[i]^ := [255, 0, 0, 0];
end.

e: I can't do much more. I can't read/write to smarts debug array correctly.

Brandon

2013-12-16 21:43:46

From: Olly
heh, Well i guess it kinda is possible to multi thread drawing on smart.
e: I can't do much more. I can't read/write to smarts debug array correctly.



Well.. for me, it's either possible or isn't. I don't believe in "kinda" ;)

Anyway, remember the problem is LibMML isn't thread safe as Dgby pointed out months ago. That doesn't mean we can't do things natively. This limitation is a SIMBA limitation and nothing more.

For example:
[ATTACH=CONFIG]22567[/ATTACH]

The above contains two plugins. One for the threading and another for image processing. Yeah it took a while to write the image stuff.

Example usage with Smart:

{$DEFINE SmartWrappers}
{$loadlib CGraphics.dll}
{$i GLX/Misc/Smart.Simba}

var
Bmp, I, J: Integer;
S: TSMart;
begin
S.Create(1024, 600);

Bmp := CG_ImageFromPointer(Pointer(S.DebugArray()), S.Width, S.Height); //Get a pointer to smart's debug buffer.

//Draw a nice square in the upper left corner of Smart.
For I := 0 To 100 DO
For J := 0 To 100 DO
CG_SetPixel(Bmp, 16777215, J, I);

CG_Clear; //Automatic garbage cleanup for all allocated bitmaps.
//CG_DeleteImage(Bmp); //Delete only one image.
end.

Another example is with two threads that draw on Smart simultaneously:

{$loadlib Threading.dll}
{$loadlib CGraphics.dll}

{$DEFINE SmartWrappers}
{$I GLXOld/Setup.Simba}

var
ThreadOne, ThreadTwo: Integer;
CImg: Integer;
StopOne, StopTwo: Boolean;

Procedure ThreadOneProc;
var
I, J: Integer;
Begin
While(Not StopOne) Do
Begin
For I := 0 To 100 Do
For J := 0 To 100 Do
CG_SetPixel(CImg, 255, J, I);
writeln('Thread One Drawing Blue');
Sleep(100);
End;
End;

Procedure ThreadTwoProc;
var
I, J: Integer;
Begin
While(Not StopTwo) Do
Begin
For I := 100 To 200 Do
For J := 100 To 200 Do
CG_SetPixel(CImg, 16777215, J, I);

writeln('Thread Two Drawing White');
Sleep(100);
End;
End;

Procedure StopThreads;
Begin
StopOne := True;
StopTwo := True;
C_JoinThread(ThreadOne);
C_JoinThread(ThreadTwo);
C_ClearThreads(False);
End;

var
Smart: TSmart;
begin
C_ClearLocks;
Smart.Create(1024, 600);
Smart.Graphics.Clear;
CImg := CG_ImageFromPointer(Pointer(Smart.DebugArray()), Smart.Width, Smart.Height);

ThreadOne := C_CreateThread(Natify(@ThreadOneProc));
ThreadTwo := C_CreateThread(Natify(@ThreadTwoProc));

AddOnTerminate('StopThreads');
CG_Clear;
end.

Example Drawing and synchronizing two threads:

{$loadlib Threading.dll}
{$loadlib CGraphics.dll}

{$DEFINE SmartWrappers}
{$I GLXOld/Setup.Simba}

var
ThreadOne, ThreadTwo, Mutex: Integer;
CImg: Integer;
StopOne, StopTwo: Boolean;

Procedure ThreadOneProc;
var
I, J: Integer;
Begin
C_Lock(Mutex);
While(Not StopOne) Do
Begin
For I := 0 To 100 Do
For J := 0 To 100 Do
CG_SetPixel(CImg, 255, J, I);
writeln('Thread One Drawing Blue');
Sleep(100);
End;
C_Unlock(Mutex);
End;

Procedure ThreadTwoProc;
var
I, J: Integer;
Begin
C_Lock(Mutex);
While(Not StopTwo) Do
Begin
For I := 100 To 200 Do
For J := 100 To 200 Do
CG_SetPixel(CImg, 16777215, J, I);

writeln('Thread Two Drawing White');
Sleep(100);
End;
C_Unlock(Mutex);
End;

Procedure StopThreads;
Begin
StopOne := True;
StopTwo := True;
C_JoinThread(ThreadOne);
C_JoinThread(ThreadTwo);
C_ClearThreads(False);
End;

var
Smart: TSmart;
begin
C_ClearLocks;
Mutex := C_CreateLock;

Smart.Create(1024, 600);
Smart.Graphics.Clear;
CImg := CG_ImageFromPointer(Pointer(Smart.DebugArray()), Smart.Width, Smart.Height);

ThreadOne := C_CreateThread(Natify(@ThreadOneProc));
ThreadTwo := C_CreateThread(Natify(@ThreadTwoProc));

Sleep(1000);
StopOne := True;
Sleep(1000);
StopTwo := True;

AddOnTerminate('StopThreads');
CG_Clear;
end.


This alone shows that you can create/load/draw any amount of images within any amount of threads as you wish. Obviously cannot use Simba's images since they are part of MML/LibMML or w/e it is called.

The only problem is that the amount of functions exported is limited (it'd take me ages to port all Simba's image manipulation crap).. The following are exported for imaging:


Function CG_CreateImage(Width, Height: Integer): Integer;
Function CG_LoadImage(FilePath: String): Integer;
Function CG_ImageFromPointer(Ptr: Pointer; Width, Height: Integer): Integer;
Function CG_ImageFromWindow(WndHandle: LongInt; X, Y, Width, Height: Integer): Integer; //Windows only.
Procedure CG_DrawToWindow(ImageID: Integer; WndHandle: LongInt; X, Y, Width, Height, SourceX, SourceY, RasterType: Integer); //Windows only.
Procedure CG_SaveImage(ImageID: Integer; FilePath: String);
Procedure CG_DeleteImage(ImageID: Integer);
Function CG_GetPixel(ImageID, X, Y: Integer): Integer;
Function CG_GetPixels(ImageID: Integer; var Width, Height: Integer): Pointer;
Procedure CG_SetPixel(ImageID, Colour, X, Y: Integer);
Procedure CG_GetDimensions(ImageID: Integer; var Width, Height: Integer);
Procedure CG_Clear;

//Not exported yet, but already written:
CG_FindBitmap
CG_FindBitmapTolerance
CG_FindBitmapToleranceIn

That's all I was able to write in the last 2 hours. Mind you, there's a lot of code behind it..
But again, these examples are only to show what is possible and how far you can break Simba's limitations. However, it'll never happen because.. See this thread's discussion so far. A lot are against it and it requires lots of new code.

I say just let this thread die.. It's been debated many times before and for so long. We already know the dev's will never allow it or add it in so why bother? There is good reason why it isn't in Simba as explained before. It's a lot of work.

Dgby714

2013-12-16 22:13:11

Actually, I said MML wasn't thread-safe, as well as Lape isn't thread-safe…

So all you really can do with it is modify script variables, and call "certain" Simba methods.

And it will prob crash with some of Lape's methods, tho that's expected.

Kevin

2013-12-17 12:10:32

From: Dgby714
Actually, I said MML wasn't thread-safe, as well as Lape isn't thread-safe…
So all you really can do with it is modify script variables, and call "certain" Simba methods.
And it will prob crash with some of Lape's methods, tho that's expected.


Why isn't MML thread-safe? Based on the functionality, there really isn't much that I see that screams impossible to write thread safely. And then of course there's this as I looked at it some more with even Wizzup thinking it's threadsafe (sorry to bring your attention to this as well, it's just this way I would have a link to the original statement).
From: Wizzup?
As far as I know libMML should be threadsafe.

So what isn't threadsafe about it, and could we work on that (individual functions, issues, improper locking, etc)? The programming language, Lape, isn't thread-safe - or is it merely our current implementation of it? Because LAPE, as I understand it, is simply another interpreter for a subset of Pascal, which can implement multi-threading fine.

Dgby714

2013-12-17 23:26:17

The only thing keeping it non-threadsafe is how we handle each scriptthread.

I can rewrite how our wrappers work, and it would be fine, tho afaik, Lape doesn't like moving threads.

Olly

2013-12-17 23:49:58

I would like to see other (more important) things in Simba being done before focusing on multi threading (if that is ever done).

just my two cents. :)

Kevin

2013-12-18 02:10:56

From: Olly
I would like to see other (more important) things in Simba being done before focusing on multi threading (if that is ever done).

just my two cents. :)


Yes… I'm getting carried away. My point is merely that someday we can do it and it should be reasonably possible. There are definitely things that would be more important as well, first and foremost.