Something like this, the command \flushhere
if placed between paragraphs tries to take a float off the deferred list and make it a here float at this point, if it succeeds it tries to pop the next deferred float and so on until it runs out.
So if you use [hp]
floats between paragraphs and put \flushhere
after subsequent paragraphs, any floats that didn't get placed "here" should be flushed out between paragraphs...
Only tested in this file, I probably missed something...

\documentclass{article}
\setcounter{totalnumber}{30}% lots of here floats
\def\a{One two \stepcounter{enumi}\roman{enumi} three four five six. }
\def\b{\a\a red \stepcounter{enumi}\roman{enumi} red green yellow
random longer typesetting expressions that might invoke hyphenation. }
\def\c{\a\b\a\a\b\b\a}
\def\f#1{\begin{figure}[hp]\centering\rule{2cm}{1cm}\par\caption{ff: #1}\end{figure}}
\def\t#1{\begin{table}[hp]\centering\caption{tt: #1}\par\bigskip\begin{tabular}{cc}1&2\\33&44\\555&666\end{tabular}\end{table}}
\makeatletter
\def\flushhere{\par{%
\let\s@deferlist\@deferlist
\let\@currbox\relax
\@next\@currbox\@deferlist{%
\ifodd\count\@currbox
\typeout{Trying \meaning\@currbox (\number\@currbox/\the\count\@currbox),
adding to \meaning\@currlist}%
\@cons\@currlist\@currbox
\typeout{added: to \meaning\@currlist}%
\typeout{deferlist was \s@deferlist, now \@deferlist}%
\let\s@@deferlist\@deferlist\@empty
\global\let\@deferlist\@empty
\@floatpenalty -\@Miii
\penalty -\@Miv
\@tempdima\prevdepth
\vbox{}%
\prevdepth\@tempdima
\penalty\@floatpenalty
\@@par
\ifx\@deferlist\@empty
\typeout{float placed here}%
\global\let\@deferlist\s@@deferlist
\flushhere
\else
\typeout{float not placed here}%
\global\let\@deferlist\s@deferlist
\fi
\else
\typeout{not h}%
\global\let\@deferlist\s@deferlist
\fi
}%
{%
\typeout{no pending float}%
}\par}}
\makeatother
%\let\flushhere\relax
\begin{document}
AA \c \verb|\t{a}\f{a}|
\t{a}\f{a}
BB \c\b \verb|\t{b}\t{c}|
\t{b}\t{c}
BB2 \b \verb|\f{b}\f{c}|
\flushhere
\f{b}\f{c}
CC2 \a
\flushhere
CC \c \verb|\t{d}|
\flushhere
\t{d}
DD \c
\typeout{before DD2}
\flushhere
DD2 \c
\flushhere
\f{d}
EE \c
\typeout{before FF}
\flushhere
FF \c\b
%\flushhere
\end{document}
[htp]
then it tries here or puts it on a queue the only difference is that the check for using the queue is at page breaks not every paragraph (doing the latter would be hard in tex, and you'd need some mechanism to prevent the floats at "internal" paragraphs where you don't want it to appear such as sections headings, list labels, etc. Because of tex's asynchronous page breaker what you ask isn't simple at all, tex may collect multiple pages worth of material before invoking the page breaker so you can not simply ask if anything fits "here" until you know the page breaking.